@angular/core
Version:
Angular - the core framework
121 lines • 17.6 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// i18nPostprocess consts
const ROOT_TEMPLATE_ID = 0;
const PP_MULTI_VALUE_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]/;
const PP_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]|(�\/?\*\d+:\d+�)/g;
const PP_ICU_VARS_REGEXP = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
const PP_ICU_PLACEHOLDERS_REGEXP = /{([A-Z0-9_]+)}/g;
const PP_ICUS_REGEXP = /�I18N_EXP_(ICU(_\d+)?)�/g;
const PP_CLOSE_TEMPLATE_REGEXP = /\/\*/;
const PP_TEMPLATE_ID_REGEXP = /\d+\:(\d+)/;
/**
* Handles message string post-processing for internationalization.
*
* Handles message string post-processing by transforming it from intermediate
* format (that might contain some markers that we need to replace) to the final
* form, consumable by i18nStart instruction. Post processing steps include:
*
* 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
* 2. Replace all ICU vars (like "VAR_PLURAL")
* 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
* 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
* in case multiple ICUs have the same placeholder name
*
* @param message Raw translation string for post processing
* @param replacements Set of replacements that should be applied
*
* @returns Transformed string that can be consumed by i18nStart instruction
*
* @codeGenApi
*/
export function i18nPostprocess(message, replacements = {}) {
/**
* Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
*
* Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
* grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
* template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
* 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
* front of �#6�. The post processing step restores the right order by keeping track of the
* template id stack and looks for placeholders that belong to the currently active template.
*/
let result = message;
if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
const matches = {};
const templateIdsStack = [ROOT_TEMPLATE_ID];
result = result.replace(PP_PLACEHOLDERS_REGEXP, (m, phs, tmpl) => {
const content = phs || tmpl;
const placeholders = matches[content] || [];
if (!placeholders.length) {
content.split('|').forEach((placeholder) => {
const match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
const templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
const isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
placeholders.push([templateId, isCloseTemplateTag, placeholder]);
});
matches[content] = placeholders;
}
if (!placeholders.length) {
throw new Error(`i18n postprocess: unmatched placeholder - ${content}`);
}
const currentTemplateId = templateIdsStack[templateIdsStack.length - 1];
let idx = 0;
// find placeholder index that matches current template id
for (let i = 0; i < placeholders.length; i++) {
if (placeholders[i][0] === currentTemplateId) {
idx = i;
break;
}
}
// update template id stack based on the current tag extracted
const [templateId, isCloseTemplateTag, placeholder] = placeholders[idx];
if (isCloseTemplateTag) {
templateIdsStack.pop();
}
else if (currentTemplateId !== templateId) {
templateIdsStack.push(templateId);
}
// remove processed tag from the list
placeholders.splice(idx, 1);
return placeholder;
});
}
// return current result if no replacements specified
if (!Object.keys(replacements).length) {
return result;
}
/**
* Step 2: replace all ICU vars (like "VAR_PLURAL")
*/
result = result.replace(PP_ICU_VARS_REGEXP, (match, start, key, _type, _idx, end) => {
return replacements.hasOwnProperty(key) ? `${start}${replacements[key]}${end}` : match;
});
/**
* Step 3: replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
*/
result = result.replace(PP_ICU_PLACEHOLDERS_REGEXP, (match, key) => {
return replacements.hasOwnProperty(key) ? replacements[key] : match;
});
/**
* Step 4: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�) in case
* multiple ICUs have the same placeholder name
*/
result = result.replace(PP_ICUS_REGEXP, (match, key) => {
if (replacements.hasOwnProperty(key)) {
const list = replacements[key];
if (!list.length) {
throw new Error(`i18n postprocess: unmatched ICU - ${match} with key: ${key}`);
}
return list.shift();
}
return match;
});
return result;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bl9wb3N0cHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaTE4bi9pMThuX3Bvc3Rwcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILHlCQUF5QjtBQUN6QixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUMzQixNQUFNLGtDQUFrQyxHQUFHLGNBQWMsQ0FBQztBQUMxRCxNQUFNLHNCQUFzQixHQUFHLGdDQUFnQyxDQUFDO0FBQ2hFLE1BQU0sa0JBQWtCLEdBQUcsMkNBQTJDLENBQUM7QUFDdkUsTUFBTSwwQkFBMEIsR0FBRyxpQkFBaUIsQ0FBQztBQUNyRCxNQUFNLGNBQWMsR0FBRywwQkFBMEIsQ0FBQztBQUNsRCxNQUFNLHdCQUF3QixHQUFHLE1BQU0sQ0FBQztBQUN4QyxNQUFNLHFCQUFxQixHQUFHLFlBQVksQ0FBQztBQU0zQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQzdCLE9BQWUsRUFDZixlQUFtRCxFQUFFO0lBRXJEOzs7Ozs7Ozs7T0FTRztJQUNILElBQUksTUFBTSxHQUFXLE9BQU8sQ0FBQztJQUM3QixJQUFJLGtDQUFrQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3JELE1BQU0sT0FBTyxHQUE4QyxFQUFFLENBQUM7UUFDOUQsTUFBTSxnQkFBZ0IsR0FBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdEQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFNLEVBQUUsR0FBVyxFQUFFLElBQVksRUFBVSxFQUFFO1lBQzVGLE1BQU0sT0FBTyxHQUFHLEdBQUcsSUFBSSxJQUFJLENBQUM7WUFDNUIsTUFBTSxZQUFZLEdBQTZCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxF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QVksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFFLFlBQVksQ0FBQyxHQUFHLENBQVksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ2xGLENBQUMsQ0FBQyxDQUFDO0lBRUg7OztPQUdHO0lBQ0gsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBVSxFQUFFO1FBQzdELElBQUksWUFBWSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQWEsQ0FBQztZQUMzQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxLQUFLLGNBQWMsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNqRixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFHLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8vIGkxOG5Qb3N0cHJvY2VzcyBjb25zdHNcbmNvbnN0IFJPT1RfVEVNUExBVEVfSUQgPSAwO1xuY29uc3QgUFBfTVVMVElfVkFMVUVfUExBQ0VIT0xERVJTX1JFR0VYUCA9IC9cXFso77+9Lis/77+9PylcXF0vO1xuY29uc3QgUFBfUExBQ0VIT0xERVJTX1JFR0VYUCA9IC9cXFso77+9Lis/77+9PylcXF18KO+/vVxcLz9cXCpcXGQrOlxcZCvvv70pL2c7XG5jb25zdCBQUF9JQ1VfVkFSU19SRUdFWFAgPSAvKHtcXHMqKShWQVJfKFBMVVJBTHxTRUxFQ1QpKF9cXGQrKT8pKFxccyosKS9nO1xuY29uc3QgUFBfSUNVX1BMQUNFSE9MREVSU19SRUdFWFAgPSAveyhbQS1aMC05X10rKX0vZztcbmNvbnN0IFBQX0lDVVNfUkVHRVhQID0gL++/vUkxOE5fRVhQXyhJQ1UoX1xcZCspPynvv70vZztcbmNvbnN0IFBQX0NMT1NFX1RFTVBMQVRFX1JFR0VYUCA9IC9cXC9cXCovO1xuY29uc3QgUFBfVEVNUExBVEVfSURfUkVHRVhQID0gL1xcZCtcXDooXFxkKykvO1xuXG4vLyBQYXJzZWQgcGxhY2Vob2xkZXIgc3RydWN0dXJlIHVzZWQgaW4gcG9zdHByb2Nlc3NpbmcgKHdpdGhpbiBgaTE4blBvc3Rwcm9jZXNzYCBmdW5jdGlvbilcbi8vIENvbnRhaW5zIHRoZSBmb2xsb3dpbmcgZmllbGRzOiBbdGVtcGxhdGVJZCwgaXNDbG9zZVRlbXBsYXRlVGFnLCBwbGFjZWhvbGRlcl1cbnR5cGUgUG9zdHByb2Nlc3NQbGFjZWhvbGRlciA9IFtudW1iZXIsIGJvb2xlYW4sIHN0cmluZ107XG5cbi8qKlxuICogSGFuZGxlcyBtZXNzYWdlIHN0cmluZyBwb3N0LXByb2Nlc3NpbmcgZm9yIGludGVybmF0aW9uYWxpemF0aW9uLlxuICpcbiAqIEhhbmRsZXMgbWVzc2FnZSBzdHJpbmcgcG9zdC1wcm9jZXNzaW5nIGJ5IHRyYW5zZm9ybWluZyBpdCBmcm9tIGludGVybWVkaWF0ZVxuICogZm9ybWF0ICh0aGF0IG1pZ2h0IGNvbnRhaW4gc29tZSBtYXJrZXJzIHRoYXQgd2UgbmVlZCB0byByZXBsYWNlKSB0byB0aGUgZmluYWxcbiAqIGZvcm0sIGNvbnN1bWFibGUgYnkgaTE4blN0YXJ0IGluc3RydWN0aW9uLiBQb3N0IHByb2Nlc3Npbmcgc3RlcHMgaW5jbHVkZTpcbiAqXG4gKiAxLiBSZXNvbHZlIGFsbCBtdWx0aS12YWx1ZSBjYXNlcyAobGlrZSBb77+9KjE6Me+/ve+/vSMyOjHvv71877+9IzQ6Me+/vXzvv70177+9XSlcbiAqIDIuIFJlcGxhY2UgYWxsIElDVSB2YXJzIChsaWtlIFwiVkFSX1BMVVJBTFwiKVxuICogMy4gUmVwbGFjZSBhbGwgcGxhY2Vob2xkZXJzIHVzZWQgaW5zaWRlIElDVXMgaW4gYSBmb3JtIG9mIHtQTEFDRUhPTERFUn1cbiAqIDQuIFJlcGxhY2UgYWxsIElDVSByZWZlcmVuY2VzIHdpdGggY29ycmVzcG9uZGluZyB2YWx1ZXMgKGxpa2Ug77+9SUNVX0VYUF9JQ1VfMe+/vSlcbiAqICAgIGluIGNhc2UgbXVsdGlwbGUgSUNVcyBoYXZlIHRoZSBzYW1lIHBsYWNlaG9sZGVyIG5hbWVcbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSBSYXcgdHJhbnNsYXRpb24gc3RyaW5nIGZvciBwb3N0IHByb2Nlc3NpbmdcbiAqIEBwYXJhbSByZXBsYWNlbWVudHMgU2V0IG9mIHJlcGxhY2VtZW50cyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkXG4gKlxuICogQHJldHVybnMgVHJhbnNmb3JtZWQgc3RyaW5nIHRoYXQgY2FuIGJlIGNvbnN1bWVkIGJ5IGkxOG5TdGFydCBpbnN0cnVjdGlvblxuICpcbiAqIEBjb2RlR2VuQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpMThuUG9zdHByb2Nlc3MoXG4gIG1lc3NhZ2U6IHN0cmluZyxcbiAgcmVwbGFjZW1lbnRzOiB7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgc3RyaW5nW119ID0ge30sXG4pOiBzdHJpbmcge1xuICAvKipcbiAgICogU3RlcCAxOiByZXNvbHZlIGFsbCBtdWx0aS12YWx1ZSBwbGFjZWhvbGRlcnMgbGlrZSBb77+9IzXvv71877+9KjE6Me+/ve+/vSMyOjHvv71877+9IzQ6Me+/vV1cbiAgICpcbiAgICogTm90ZTogZHVlIHRvIHRoZSB3YXkgd2UgcHJvY2VzcyBuZXN0ZWQgdGVtcGxhdGVzIChCRlMpLCBtdWx0aS12YWx1ZSBwbGFjZWhvbGRlcnMgYXJlIHR5cGljYWxseVxuICAgKiBncm91cGVkIGJ5IHRlbXBsYXRlcywgZm9yIGV4YW1wbGU6IFvvv70jNe+/vXzvv70jNu+/vXzvv70jMTox77+9fO+/vSMzOjLvv71dIHdoZXJlIO+/vSM177+9IGFuZCDvv70jNu+/vSBiZWxvbmcgdG8gcm9vdFxuICAgKiB0ZW1wbGF0ZSwg77+9IzE6Me+/vSBiZWxvbmcgdG8gbmVzdGVkIHRlbXBsYXRlIHdpdGggaW5kZXggMSBhbmQg77+9IzE6Mu+/vSAtIG5lc3RlZCB0ZW1wbGF0ZSB3aXRoIGluZGV4XG4gICAqIDMuIEhvd2V2ZXIgaW4gcmVhbCB0ZW1wbGF0ZXMgdGhlIG9yZGVyIG1pZ2h0IGJlIGRpZmZlcmVudDogaS5lLiDvv70jMTox77+9IGFuZC9vciDvv70jMzoy77+9IG1heSBnbyBpblxuICAgKiBmcm9udCBvZiDvv70jNu+/vS4gVGhlIHBvc3QgcHJvY2Vzc2luZyBzdGVwIHJlc3RvcmVzIHRoZSByaWdodCBvcmRlciBieSBrZWVwaW5nIHRyYWNrIG9mIHRoZVxuICAgKiB0ZW1wbGF0ZSBpZCBzdGFjayBhbmQgbG9va3MgZm9yIHBsYWNlaG9sZGVycyB0aGF0IGJlbG9uZyB0byB0aGUgY3VycmVudGx5IGFjdGl2ZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGxldCByZXN1bHQ6IHN0cmluZyA9IG1lc3NhZ2U7XG4gIGlmIChQUF9NVUxUSV9WQUxVRV9QTEFDRUhPTERFUlNfUkVHRVhQLnRlc3QobWVzc2FnZSkpIHtcbiAgICBjb25zdCBtYXRjaGVzOiB7W2tleTogc3RyaW5nXTogUG9zdHByb2Nlc3NQbGFjZWhvbGRlcltdfSA9IHt9O1xuICAgIGNvbnN0IHRlbXBsYXRlSWRzU3RhY2s6IG51bWJlcltdID0gW1JPT1RfVEVNUExBVEVfSURdO1xuICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKFBQX1BMQUNFSE9MREVSU19SRUdFWFAsIChtOiBhbnksIHBoczogc3RyaW5nLCB0bXBsOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgY29uc3QgY29udGVudCA9IHBocyB8fCB0bXBsO1xuICAgICAgY29uc3QgcGxhY2Vob2xkZXJzOiBQb3N0cHJvY2Vzc1BsYWNlaG9sZGVyW10gPSBtYXRjaGVzW2NvbnRlbnRdIHx8IFtdO1xuICAgICAgaWYgKCFwbGFjZWhvbGRlcnMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnRlbnQuc3BsaXQoJ3wnKS5mb3JFYWNoKChwbGFjZWhvbGRlcjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBwbGFjZWhvbGRlci5tYXRjaChQUF9URU1QTEFURV9JRF9SRUdFWFApO1xuICAgICAgICAgIGNvbnN0IHRlbXBsYXRlSWQgPSBtYXRjaCA/IHBhcnNlSW50KG1hdGNoWzFdLCAxMCkgOiBST09UX1RFTVBMQVRFX0lEO1xuICAgICAgICAgIGNvbnN0IGlzQ2xvc2VUZW1wbGF0ZVRhZyA9IFBQX0NMT1NFX1RFTVBMQVRFX1JFR0VYUC50ZXN0KHBsYWNlaG9sZGVyKTtcbiAgICAgICAgICBwbGFjZWhvbGRlcnMucHVzaChbdGVtcGxhdGVJZCwgaXNDbG9zZVRlbXBsYXRlVGFnLCBwbGFjZWhvbGRlcl0pO1xuICAgICAgICB9KTtcbiAgICAgICAgbWF0Y2hlc1tjb250ZW50XSA9IHBsYWNlaG9sZGVycztcbiAgICAgIH1cblxuICAgICAgaWYgKCFwbGFjZWhvbGRlcnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaTE4biBwb3N0cHJvY2VzczogdW5tYXRjaGVkIHBsYWNlaG9sZGVyIC0gJHtjb250ZW50fWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjdXJyZW50VGVtcGxhdGVJZCA9IHRlbXBsYXRlSWRzU3RhY2tbdGVtcGxhdGVJZHNTdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIGxldCBpZHggPSAwO1xuICAgICAgLy8gZmluZCBwbGFjZWhvbGRlciBpbmRleCB0aGF0IG1hdGNoZXMgY3VycmVudCB0ZW1wbGF0ZSBpZFxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwbGFjZWhvbGRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyc1tpXVswXSA9PT0gY3VycmVudFRlbXBsYXRlSWQpIHtcbiAgICAgICAgICBpZHggPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyB1cGRhdGUgdGVtcGxhdGUgaWQgc3RhY2sgYmFzZWQgb24gdGhlIGN1cnJlbnQgdGFnIGV4dHJhY3RlZFxuICAgICAgY29uc3QgW3RlbXBsYXRlSWQsIGlzQ2xvc2VUZW1wbGF0ZVRhZywgcGxhY2Vob2xkZXJdID0gcGxhY2Vob2xkZXJzW2lkeF07XG4gICAgICBpZiAoaXNDbG9zZVRlbXBsYXRlVGFnKSB7XG4gICAgICAgIHRlbXBsYXRlSWRzU3RhY2sucG9wKCk7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRUZW1wbGF0ZUlkICE9PSB0ZW1wbGF0ZUlkKSB7XG4gICAgICAgIHRlbXBsYXRlSWRzU3RhY2sucHVzaCh0ZW1wbGF0ZUlkKTtcbiAgICAgIH1cbiAgICAgIC8vIHJlbW92ZSBwcm9jZXNzZWQgdGFnIGZyb20gdGhlIGxpc3RcbiAgICAgIHBsYWNlaG9sZGVycy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHJldHVybiBjdXJyZW50IHJlc3VsdCBpZiBubyByZXBsYWNlbWVudHMgc3BlY2lmaWVkXG4gIGlmICghT2JqZWN0LmtleXMocmVwbGFjZW1lbnRzKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0ZXAgMjogcmVwbGFjZSBhbGwgSUNVIHZhcnMgKGxpa2UgXCJWQVJfUExVUkFMXCIpXG4gICAqL1xuICByZXN1bHQgPSByZXN1bHQucmVwbGFjZShQUF9JQ1VfVkFSU19SRUdFWFAsIChtYXRjaCwgc3RhcnQsIGtleSwgX3R5cGUsIF9pZHgsIGVuZCk6IHN0cmluZyA9PiB7XG4gICAgcmV0dXJuIHJlcGxhY2VtZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpID8gYCR7c3RhcnR9JHtyZXBsYWNlbWVudHNba2V5XX0ke2VuZH1gIDogbWF0Y2g7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBTdGVwIDM6IHJlcGxhY2UgYWxsIHBsYWNlaG9sZGVycyB1c2VkIGluc2lkZSBJQ1VzIGluIGEgZm9ybSBvZiB7UExBQ0VIT0xERVJ9XG4gICAqL1xuICByZXN1bHQgPSByZXN1bHQucmVwbGFjZShQUF9JQ1VfUExBQ0VIT0xERVJTX1JFR0VYUCwgKG1hdGNoLCBrZXkpOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiByZXBsYWNlbWVudHMuaGFzT3duUHJvcGVydHkoa2V5KSA/IChyZXBsYWNlbWVudHNba2V5XSBhcyBzdHJpbmcpIDogbWF0Y2g7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBTdGVwIDQ6IHJlcGxhY2UgYWxsIElDVSByZWZlcmVuY2VzIHdpdGggY29ycmVzcG9uZGluZyB2YWx1ZXMgKGxpa2Ug77+9SUNVX0VYUF9JQ1VfMe+/vSkgaW4gY2FzZVxuICAgKiBtdWx0aXBsZSBJQ1VzIGhhdmUgdGhlIHNhbWUgcGxhY2Vob2xkZXIgbmFtZVxuICAgKi9cbiAgcmVzdWx0ID0gcmVzdWx0LnJlcGxhY2UoUFBfSUNVU19SRUdFWFAsIChtYXRjaCwga2V5KTogc3RyaW5nID0+IHtcbiAgICBpZiAocmVwbGFjZW1lbnRzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnN0IGxpc3QgPSByZXBsYWNlbWVudHNba2V5XSBhcyBzdHJpbmdbXTtcbiAgICAgIGlmICghbGlzdC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpMThuIHBvc3Rwcm9jZXNzOiB1bm1hdGNoZWQgSUNVIC0gJHttYXRjaH0gd2l0aCBrZXk6ICR7a2V5fWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxpc3Quc2hpZnQoKSE7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaDtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==