UNPKG

@angular/flex-layout

Version:
129 lines 16.9 kB
import { DOCUMENT } from '@angular/common'; import { BEFORE_APP_SERIALIZED } from '@angular/platform-server'; import { BREAKPOINTS, CLASS_NAME, SERVER_TOKEN, ɵMatchMedia as MatchMedia, StylesheetMap, sortAscendingPriority } from '@angular/flex-layout/core'; import { ServerMatchMedia } from './server-match-media'; /** * Activate all of the registered breakpoints in sequence, and then * retrieve the associated stylings from the virtual stylesheet * @param serverSheet the virtual stylesheet that stores styles for each * element * @param mediaController the MatchMedia service to activate/deactivate breakpoints * @param breakpoints the registered breakpoints to activate/deactivate * @param layoutConfig the library config, and specifically the breakpoints to activate */ export function generateStaticFlexLayoutStyles(serverSheet, mediaController, breakpoints) { // Store the custom classes in the following map, that way only // one class gets allocated per HTMLElement, and each class can // be referenced in the static media queries const classMap = new Map(); // Get the initial stylings for all of the directives, // and initialize the fallback block of stylings const defaultStyles = new Map(serverSheet.stylesheet); // Reset the class counter, otherwise class numbers will // increase with each server render nextId = 0; let styleText = generateCss(defaultStyles, 'all', classMap); [...breakpoints].sort(sortAscendingPriority).forEach((bp, i) => { serverSheet.clearStyles(); mediaController.activateBreakpoint(bp); const stylesheet = new Map(serverSheet.stylesheet); if (stylesheet.size > 0) { styleText += generateCss(stylesheet, bp.mediaQuery, classMap); } mediaController.deactivateBreakpoint(breakpoints[i]); }); return styleText; } /** * Create a style tag populated with the dynamic stylings from Flex * components and attach it to the head of the DOM */ export function FLEX_SSR_SERIALIZER_FACTORY(serverSheet, mediaController, _document, breakpoints) { return () => { // This is the style tag that gets inserted into the head of the DOM, // populated with the manual media queries const styleTag = _document.createElement('style'); const styleText = generateStaticFlexLayoutStyles(serverSheet, mediaController, breakpoints); styleTag.classList.add(`${CLASS_NAME}ssr`); styleTag.textContent = styleText; _document.head.appendChild(styleTag); }; } /** * Provider to set static styles on the server */ export const SERVER_PROVIDERS = [ { provide: BEFORE_APP_SERIALIZED, useFactory: FLEX_SSR_SERIALIZER_FACTORY, deps: [ StylesheetMap, MatchMedia, DOCUMENT, BREAKPOINTS ], multi: true }, { provide: SERVER_TOKEN, useValue: true }, { provide: MatchMedia, useClass: ServerMatchMedia } ]; let nextId = 0; const IS_DEBUG_MODE = false; /** * create @media queries based on a virtual stylesheet * * Adds a unique class to each element and stores it * in a shared classMap for later reuse * @param stylesheet the virtual stylesheet that stores styles for each * element * @param mediaQuery the given @media CSS selector for the current breakpoint * @param classMap the map of HTML elements to class names to avoid duplications */ function generateCss(stylesheet, mediaQuery, classMap) { let css = ''; stylesheet.forEach((styles, el) => { let keyVals = ''; let className = getClassName(el, classMap); styles.forEach((v, k) => { keyVals += v ? format(`${k}:${v};`) : ''; }); // Build list of CSS styles; each with a className css += format(`.${className} {`, keyVals, '}'); }); // Group 1 or more styles (each with className) in a specific mediaQuery return format(`@media ${mediaQuery} {`, css, '}'); } /** * For debugging purposes, prefix css segment with linefeed(s) for easy * debugging purposes. */ function format(...list) { let result = ''; list.forEach((css, i) => { result += IS_DEBUG_MODE ? formatSegment(css, i !== 0) : css; }); return result; } function formatSegment(css, asPrefix = true) { return asPrefix ? `\n${css}` : `${css}\n`; } /** * Get className associated with CSS styling * If not found, generate global className and set * association. */ function getClassName(element, classMap) { let className = classMap.get(element); if (!className) { className = `${CLASS_NAME}${nextId++}`; classMap.set(element, className); } element.classList.add(className); return className; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbGlicy9mbGV4LWxheW91dC9zZXJ2ZXIvc2VydmVyLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRCxPQUFPLEVBQ0wsV0FBVyxFQUNYLFVBQVUsRUFDVixZQUFZLEVBRVosV0FBVyxJQUFJLFVBQVUsRUFDekIsYUFBYSxFQUNiLHFCQUFxQixFQUN0QixNQUFNLDJCQUEyQixDQUFDO0FBRW5DLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBRXREOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QixDQUFDLFdBQTBCLEVBQzFCLGVBQWlDLEVBQ2pDLFdBQXlCO0lBQ3RFLCtEQUErRDtJQUMvRCwrREFBK0Q7SUFDL0QsNENBQTRDO0lBQzVDLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBRWhELHNEQUFzRDtJQUN0RCxnREFBZ0Q7SUFDaEQsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELHdEQUF3RDtJQUN4RCxtQ0FBbUM7SUFDbkMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNYLElBQUksU0FBUyxHQUFHLFdBQVcsQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRTVELENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDN0QsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzFCLGVBQWUs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T0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3RCLE1BQU0sSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsR0FBVyxFQUFFLFdBQW9CLElBQUk7SUFDMUQsT0FBTyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxPQUFvQixFQUFFLFFBQWtDO0lBQzVFLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLFNBQVMsRUFBRTtRQUNkLFNBQVMsR0FBRyxHQUFHLFVBQVUsR0FBRyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ3ZDLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ2xDO0lBQ0QsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFakMsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHtJbmplY3Rpb25Ub2tlbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtCRUZPUkVfQVBQX1NFUklBTElaRUR9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLXNlcnZlcic7XG5pbXBvcnQge1xuICBCUkVBS1BPSU5UUyxcbiAgQ0xBU1NfTkFNRSxcbiAgU0VSVkVSX1RPS0VOLFxuICBCcmVha1BvaW50LFxuICDJtU1hdGNoTWVkaWEgYXMgTWF0Y2hNZWRpYSxcbiAgU3R5bGVzaGVldE1hcCxcbiAgc29ydEFzY2VuZGluZ1ByaW9yaXR5XG59IGZyb20gJ0Bhbmd1bGFyL2ZsZXgtbGF5b3V0L2NvcmUnO1xuXG5pbXBvcnQge1NlcnZlck1hdGNoTWVkaWF9IGZyb20gJy4vc2VydmVyLW1hdGNoLW1lZGlhJztcblxuLyoqXG4gKiBBY3RpdmF0ZSBhbGwgb2YgdGhlIHJlZ2lzdGVyZWQgYnJlYWtwb2ludHMgaW4gc2VxdWVuY2UsIGFuZCB0aGVuXG4gKiByZXRyaWV2ZSB0aGUgYXNzb2NpYXRlZCBzdHlsaW5ncyBmcm9tIHRoZSB2aXJ0dWFsIHN0eWxlc2hlZXRcbiAqIEBwYXJhbSBzZXJ2ZXJTaGVldCB0aGUgdmlydHVhbCBzdHlsZXNoZWV0IHRoYXQgc3RvcmVzIHN0eWxlcyBmb3IgZWFjaFxuICogICAgICAgIGVsZW1lbnRcbiAqIEBwYXJhbSBtZWRpYUNvbnRyb2xsZXIgdGhlIE1hdGNoTWVkaWEgc2VydmljZSB0byBhY3RpdmF0ZS9kZWFjdGl2YXRlIGJyZWFrcG9pbnRzXG4gKiBAcGFyYW0gYnJlYWtwb2ludHMgdGhlIHJlZ2lzdGVyZWQgYnJlYWtwb2ludHMgdG8gYWN0aXZhdGUvZGVhY3RpdmF0ZVxuICogQHBhcmFtIGxheW91dENvbmZpZyB0aGUgbGlicmFyeSBjb25maWcsIGFuZCBzcGVjaWZpY2FsbHkgdGhlIGJyZWFrcG9pbnRzIHRvIGFjdGl2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVN0YXRpY0ZsZXhMYXlvdXRTdHlsZXMoc2VydmVyU2hlZXQ6IFN0eWxlc2hlZXRNYXAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhQ29udHJvbGxlcjogU2VydmVyTWF0Y2hNZWRpYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtwb2ludHM6IEJyZWFrUG9pbnRbXSkge1xuICAvLyBTdG9yZSB0aGUgY3VzdG9tIGNsYXNzZXMgaW4gdGhlIGZvbGxvd2luZyBtYXAsIHRoYXQgd2F5IG9ubHlcbiAgLy8gb25lIGNsYXNzIGdldHMgYWxsb2NhdGVkIHBlciBIVE1MRWxlbWVudCwgYW5kIGVhY2ggY2xhc3MgY2FuXG4gIC8vIGJlIHJlZmVyZW5jZWQgaW4gdGhlIHN0YXRpYyBtZWRpYSBxdWVyaWVzXG4gIGNvbnN0IGNsYXNzTWFwID0gbmV3IE1hcDxIVE1MRWxlbWVudCwgc3RyaW5nPigpO1xuXG4gIC8vIEdldCB0aGUgaW5pdGlhbCBzdHlsaW5ncyBmb3IgYWxsIG9mIHRoZSBkaXJlY3RpdmVzLFxuICAvLyBhbmQgaW5pdGlhbGl6ZSB0aGUgZmFsbGJhY2sgYmxvY2sgb2Ygc3R5bGluZ3NcbiAgY29uc3QgZGVmYXVsdFN0eWxlcyA9IG5ldyBNYXAoc2VydmVyU2hlZXQuc3R5bGVzaGVldCk7XG4gIC8vIFJlc2V0IHRoZSBjbGFzcyBjb3VudGVyLCBvdGhlcndpc2UgY2xhc3MgbnVtYmVycyB3aWxsXG4gIC8vIGluY3JlYXNlIHdpdGggZWFjaCBzZXJ2ZXIgcmVuZGVyXG4gIG5leHRJZCA9IDA7XG4gIGxldCBzdHlsZVRleHQgPSBnZW5lcmF0ZUNzcyhkZWZhdWx0U3R5bGVzLCAnYWxsJywgY2xhc3NNYXApO1xuXG4gIFsuLi5icmVha3BvaW50c10uc29ydChzb3J0QXNjZW5kaW5nUHJpb3JpdHkpLmZvckVhY2goKGJwLCBpKSA9PiB7XG4gICAgc2VydmVyU2hlZXQuY2xlYXJTdHlsZXMoKTtcbiAgICBtZWRpYUNvbnRyb2xsZXIuYWN0aXZhdGVCcmVha3BvaW50KGJwKTtcbiAgICBjb25zdCBzdHlsZXNoZWV0ID0gbmV3IE1hcChzZXJ2ZXJTaGVldC5zdHlsZXNoZWV0KTtcbiAgICBpZiAoc3R5bGVzaGVldC5zaXplID4gMCkge1xuICAgICAgc3R5bGVUZXh0ICs9IGdlbmVyYXRlQ3NzKHN0eWxlc2hlZXQsIGJwLm1lZGlhUXVlcnksIGNsYXNzTWFwKTtcbiAgICB9XG4gICAgbWVkaWFDb250cm9sbGVyLmRlYWN0aXZhdGVCcmVha3BvaW50KGJyZWFrcG9pbnRzW2ldKTtcbiAgfSk7XG5cblxuXG4gIHJldHVybiBzdHlsZVRleHQ7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc3R5bGUgdGFnIHBvcHVsYXRlZCB3aXRoIHRoZSBkeW5hbWljIHN0eWxpbmdzIGZyb20gRmxleFxuICogY29tcG9uZW50cyBhbmQgYXR0YWNoIGl0IHRvIHRoZSBoZWFkIG9mIHRoZSBET01cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEZMRVhfU1NSX1NFUklBTElaRVJfRkFDVE9SWShzZXJ2ZXJTaGVldDogU3R5bGVzaGVldE1hcCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb250cm9sbGVyOiBTZXJ2ZXJNYXRjaE1lZGlhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZG9jdW1lbnQ6IERvY3VtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3BvaW50czogQnJlYWtQb2ludFtdKSB7XG4gIHJldHVybiAoKSA9PiB7XG4gICAgLy8gVGhpcyBpcyB0aGUgc3R5bGUgdGFnIHRoYXQgZ2V0cyBpbnNlcnRlZCBpbnRvIHRoZSBoZWFkIG9mIHRoZSBET00sXG4gICAgLy8gcG9wdWxhdGVkIHdpdGggdGhlIG1hbnVhbCBtZWRpYSBxdWVyaWVzXG4gICAgY29uc3Qgc3R5bGVUYWcgPSBfZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICBjb25zdCBzdHlsZVRleHQgPSBnZW5lcmF0ZVN0YXRpY0ZsZXhMYXlvdXRTdHlsZXMoc2VydmVyU2hlZXQsIG1lZGlhQ29udHJvbGxlciwgYnJlYWtwb2ludHMpO1xuICAgIHN0eWxlVGFnLmNsYXNzTGlzdC5hZGQoYCR7Q0xBU1NfTkFNRX1zc3JgKTtcbiAgICBzdHlsZVRhZy50ZXh0Q29udGVudCA9IHN0eWxlVGV4dDtcbiAgICBfZG9jdW1lbnQuaGVhZCEuYXBwZW5kQ2hpbGQoc3R5bGVUYWcpO1xuICB9O1xufVxuXG4vKipcbiAqICBQcm92aWRlciB0byBzZXQgc3RhdGljIHN0eWxlcyBvbiB0aGUgc2VydmVyXG4gKi9cbmV4cG9ydCBjb25zdCBTRVJWRVJfUFJPVklERVJTID0gW1xuICB7XG4gICAgcHJvdmlkZTogPEluamVjdGlvblRva2VuPCgpID0+IHZvaWQ+PkJFRk9SRV9BUFBfU0VSSUFMSVpFRCxcbiAgICB1c2VGYWN0b3J5OiBGTEVYX1NTUl9TRVJJQUxJWkVSX0ZBQ1RPUlksXG4gICAgZGVwczogW1xuICAgICAgU3R5bGVzaGVldE1hcCxcbiAgICAgIE1hdGNoTWVkaWEsXG4gICAgICBET0NVTUVOVCxcbiAgICAgIEJSRUFLUE9JTlRTXG4gICAgXSxcbiAgICBtdWx0aTogdHJ1ZVxuICB9LFxuICB7XG4gICAgcHJvdmlkZTogU0VSVkVSX1RPS0VOLFxuICAgIHVzZVZhbHVlOiB0cnVlXG4gIH0sXG4gIHtcbiAgICBwcm92aWRlOiBNYXRjaE1lZGlhLFxuICAgIHVzZUNsYXNzOiBTZXJ2ZXJNYXRjaE1lZGlhXG4gIH1cbl07XG5cblxubGV0IG5leHRJZCA9IDA7XG5jb25zdCBJU19ERUJVR19NT0RFID0gZmFsc2U7XG5cbmV4cG9ydCB0eXBlIFN0eWxlU2hlZXQgPSBNYXA8SFRNTEVsZW1lbnQsIE1hcDxzdHJpbmcsIHN0cmluZ3xudW1iZXI+PjtcbmV4cG9ydCB0eXBlIENsYXNzTWFwID0gTWFwPEhUTUxFbGVtZW50LCBzdHJpbmc+O1xuXG4vKipcbiAqIGNyZWF0ZSBAbWVkaWEgcXVlcmllcyBiYXNlZCBvbiBhIHZpcnR1YWwgc3R5bGVzaGVldFxuICogKiBBZGRzIGEgdW5pcXVlIGNsYXNzIHRvIGVhY2ggZWxlbWVudCBhbmQgc3RvcmVzIGl0XG4gKiAgIGluIGEgc2hhcmVkIGNsYXNzTWFwIGZvciBsYXRlciByZXVzZVxuICogQHBhcmFtIHN0eWxlc2hlZXQgdGhlIHZpcnR1YWwgc3R5bGVzaGVldCB0aGF0IHN0b3JlcyBzdHlsZXMgZm9yIGVhY2hcbiAqICAgICAgICBlbGVtZW50XG4gKiBAcGFyYW0gbWVkaWFRdWVyeSB0aGUgZ2l2ZW4gQG1lZGlhIENTUyBzZWxlY3RvciBmb3IgdGhlIGN1cnJlbnQgYnJlYWtwb2ludFxuICogQHBhcmFtIGNsYXNzTWFwIHRoZSBtYXAgb2YgSFRNTCBlbGVtZW50cyB0byBjbGFzcyBuYW1lcyB0byBhdm9pZCBkdXBsaWNhdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVDc3Moc3R5bGVzaGVldDogU3R5bGVTaGVldCwgbWVkaWFRdWVyeTogc3RyaW5nLCBjbGFzc01hcDogQ2xhc3NNYXApIHtcbiAgbGV0IGNzcyA9ICcnO1xuICBzdHlsZXNoZWV0LmZvckVhY2goKHN0eWxlcywgZWwpID0+IHtcbiAgICBsZXQga2V5VmFscyA9ICcnO1xuICAgIGxldCBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUoZWwsIGNsYXNzTWFwKTtcblxuICAgIHN0eWxlcy5mb3JFYWNoKCh2LCBrKSA9PiB7XG4gICAgICBrZXlWYWxzICs9IHYgPyBmb3JtYXQoYCR7a306JHt2fTtgKSA6ICcnO1xuICAgIH0pO1xuXG4gICAgLy8gQnVpbGQgbGlzdCBvZiBDU1Mgc3R5bGVzOyBlYWNoIHdpdGggYSBjbGFzc05hbWVcbiAgICBjc3MgKz0gZm9ybWF0KGAuJHtjbGFzc05hbWV9IHtgLCBrZXlWYWxzLCAnfScpO1xuICB9KTtcblxuICAvLyBHcm91cCAxIG9yIG1vcmUgc3R5bGVzIChlYWNoIHdpdGggY2xhc3NOYW1lKSBpbiBhIHNwZWNpZmljIG1lZGlhUXVlcnlcbiAgcmV0dXJuIGZvcm1hdChgQG1lZGlhICR7bWVkaWFRdWVyeX0ge2AsIGNzcywgJ30nKTtcbn1cblxuLyoqXG4gKiBGb3IgZGVidWdnaW5nIHB1cnBvc2VzLCBwcmVmaXggY3NzIHNlZ21lbnQgd2l0aCBsaW5lZmVlZChzKSBmb3IgZWFzeVxuICAqIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0KC4uLmxpc3Q6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBsaXN0LmZvckVhY2goKGNzcywgaSkgPT4ge1xuICAgIHJlc3VsdCArPSBJU19ERUJVR19NT0RFID8gZm9ybWF0U2VnbWVudChjc3MsIGkgIT09IDApIDogY3NzO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0U2VnbWVudChjc3M6IHN0cmluZywgYXNQcmVmaXg6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nIHtcbiAgcmV0dXJuIGFzUHJlZml4ID8gYFxcbiR7Y3NzfWAgOiBgJHtjc3N9XFxuYDtcbn1cblxuLyoqXG4gKiBHZXQgY2xhc3NOYW1lIGFzc29jaWF0ZWQgd2l0aCBDU1Mgc3R5bGluZ1xuICogSWYgbm90IGZvdW5kLCBnZW5lcmF0ZSBnbG9iYWwgY2xhc3NOYW1lIGFuZCBzZXRcbiAqIGFzc29jaWF0aW9uLlxuICovXG5mdW5jdGlvbiBnZXRDbGFzc05hbWUoZWxlbWVudDogSFRNTEVsZW1lbnQsIGNsYXNzTWFwOiBNYXA8SFRNTEVsZW1lbnQsIHN0cmluZz4pIHtcbiAgbGV0IGNsYXNzTmFtZSA9IGNsYXNzTWFwLmdldChlbGVtZW50KTtcbiAgaWYgKCFjbGFzc05hbWUpIHtcbiAgICBjbGFzc05hbWUgPSBgJHtDTEFTU19OQU1FfSR7bmV4dElkKyt9YDtcbiAgICBjbGFzc01hcC5zZXQoZWxlbWVudCwgY2xhc3NOYW1lKTtcbiAgfVxuICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcblxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuIl19