1 | ;
|
2 | /**
|
3 | * @license
|
4 | * Copyright Google LLC All Rights Reserved.
|
5 | *
|
6 | * Use of this source code is governed by an MIT-style license that can be
|
7 | * found in the LICENSE file at https://angular.io/license
|
8 | */
|
9 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
10 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | exports.loadTranslations = exports.configureI18nBuild = exports.createI18nOptions = void 0;
|
14 | const core_1 = require("@angular-devkit/core");
|
15 | const fs_1 = __importDefault(require("fs"));
|
16 | const module_1 = __importDefault(require("module"));
|
17 | const os_1 = __importDefault(require("os"));
|
18 | const path_1 = __importDefault(require("path"));
|
19 | const schema_1 = require("../builders/browser/schema");
|
20 | const read_tsconfig_1 = require("../utils/read-tsconfig");
|
21 | const load_translations_1 = require("./load-translations");
|
22 | /**
|
23 | * The base module location used to search for locale specific data.
|
24 | */
|
25 | const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global';
|
26 | function normalizeTranslationFileOption(option, locale, expectObjectInError) {
|
27 | if (typeof option === 'string') {
|
28 | return [option];
|
29 | }
|
30 | if (Array.isArray(option) && option.every((element) => typeof element === 'string')) {
|
31 | return option;
|
32 | }
|
33 | let errorMessage = `Project i18n locales translation field value for '${locale}' is malformed. `;
|
34 | if (expectObjectInError) {
|
35 | errorMessage += 'Expected a string, array of strings, or object.';
|
36 | }
|
37 | else {
|
38 | errorMessage += 'Expected a string or array of strings.';
|
39 | }
|
40 | throw new Error(errorMessage);
|
41 | }
|
42 | function createI18nOptions(metadata, inline) {
|
43 | if (metadata.i18n !== undefined && !core_1.json.isJsonObject(metadata.i18n)) {
|
44 | throw new Error('Project i18n field is malformed. Expected an object.');
|
45 | }
|
46 | metadata = metadata.i18n || {};
|
47 | const i18n = {
|
48 | inlineLocales: new Set(),
|
49 | // en-US is the default locale added to Angular applications (https://angular.io/guide/i18n#i18n-pipes)
|
50 | sourceLocale: 'en-US',
|
51 | locales: {},
|
52 | get shouldInline() {
|
53 | return this.inlineLocales.size > 0;
|
54 | },
|
55 | };
|
56 | let rawSourceLocale;
|
57 | let rawSourceLocaleBaseHref;
|
58 | if (core_1.json.isJsonObject(metadata.sourceLocale)) {
|
59 | rawSourceLocale = metadata.sourceLocale.code;
|
60 | if (metadata.sourceLocale.baseHref !== undefined &&
|
61 | typeof metadata.sourceLocale.baseHref !== 'string') {
|
62 | throw new Error('Project i18n sourceLocale baseHref field is malformed. Expected a string.');
|
63 | }
|
64 | rawSourceLocaleBaseHref = metadata.sourceLocale.baseHref;
|
65 | }
|
66 | else {
|
67 | rawSourceLocale = metadata.sourceLocale;
|
68 | }
|
69 | if (rawSourceLocale !== undefined) {
|
70 | if (typeof rawSourceLocale !== 'string') {
|
71 | throw new Error('Project i18n sourceLocale field is malformed. Expected a string.');
|
72 | }
|
73 | i18n.sourceLocale = rawSourceLocale;
|
74 | i18n.hasDefinedSourceLocale = true;
|
75 | }
|
76 | i18n.locales[i18n.sourceLocale] = {
|
77 | files: [],
|
78 | baseHref: rawSourceLocaleBaseHref,
|
79 | };
|
80 | if (metadata.locales !== undefined && !core_1.json.isJsonObject(metadata.locales)) {
|
81 | throw new Error('Project i18n locales field is malformed. Expected an object.');
|
82 | }
|
83 | else if (metadata.locales) {
|
84 | for (const [locale, options] of Object.entries(metadata.locales)) {
|
85 | let translationFiles;
|
86 | let baseHref;
|
87 | if (core_1.json.isJsonObject(options)) {
|
88 | translationFiles = normalizeTranslationFileOption(options.translation, locale, false);
|
89 | if (typeof options.baseHref === 'string') {
|
90 | baseHref = options.baseHref;
|
91 | }
|
92 | }
|
93 | else {
|
94 | translationFiles = normalizeTranslationFileOption(options, locale, true);
|
95 | }
|
96 | if (locale === i18n.sourceLocale) {
|
97 | throw new Error(`An i18n locale ('${locale}') cannot both be a source locale and provide a translation.`);
|
98 | }
|
99 | i18n.locales[locale] = {
|
100 | files: translationFiles.map((file) => ({ path: file })),
|
101 | baseHref,
|
102 | };
|
103 | }
|
104 | }
|
105 | if (inline === true) {
|
106 | i18n.inlineLocales.add(i18n.sourceLocale);
|
107 | Object.keys(i18n.locales).forEach((locale) => i18n.inlineLocales.add(locale));
|
108 | }
|
109 | else if (inline) {
|
110 | for (const locale of inline) {
|
111 | if (!i18n.locales[locale] && i18n.sourceLocale !== locale) {
|
112 | throw new Error(`Requested locale '${locale}' is not defined for the project.`);
|
113 | }
|
114 | i18n.inlineLocales.add(locale);
|
115 | }
|
116 | }
|
117 | return i18n;
|
118 | }
|
119 | exports.createI18nOptions = createI18nOptions;
|
120 | async function configureI18nBuild(context, options) {
|
121 | if (!context.target) {
|
122 | throw new Error('The builder requires a target.');
|
123 | }
|
124 | const buildOptions = { ...options };
|
125 | const tsConfig = await (0, read_tsconfig_1.readTsconfig)(buildOptions.tsConfig, context.workspaceRoot);
|
126 | const metadata = await context.getProjectMetadata(context.target);
|
127 | const i18n = createI18nOptions(metadata, buildOptions.localize);
|
128 | // No additional processing needed if no inlining requested and no source locale defined.
|
129 | if (!i18n.shouldInline && !i18n.hasDefinedSourceLocale) {
|
130 | return { buildOptions, i18n };
|
131 | }
|
132 | const projectRoot = path_1.default.join(context.workspaceRoot, metadata.root || '');
|
133 | // The trailing slash is required to signal that the path is a directory and not a file.
|
134 | const projectRequire = module_1.default.createRequire(projectRoot + '/');
|
135 | const localeResolver = (locale) => projectRequire.resolve(path_1.default.join(LOCALE_DATA_BASE_MODULE, locale));
|
136 | // Load locale data and translations (if present)
|
137 | let loader;
|
138 | const usedFormats = new Set();
|
139 | for (const [locale, desc] of Object.entries(i18n.locales)) {
|
140 | if (!i18n.inlineLocales.has(locale) && locale !== i18n.sourceLocale) {
|
141 | continue;
|
142 | }
|
143 | let localeDataPath = findLocaleDataPath(locale, localeResolver);
|
144 | if (!localeDataPath) {
|
145 | const [first] = locale.split('-');
|
146 | if (first) {
|
147 | localeDataPath = findLocaleDataPath(first.toLowerCase(), localeResolver);
|
148 | if (localeDataPath) {
|
149 | context.logger.warn(`Locale data for '${locale}' cannot be found. Using locale data for '${first}'.`);
|
150 | }
|
151 | }
|
152 | }
|
153 | if (!localeDataPath) {
|
154 | context.logger.warn(`Locale data for '${locale}' cannot be found. No locale data will be included for this locale.`);
|
155 | }
|
156 | else {
|
157 | desc.dataPath = localeDataPath;
|
158 | }
|
159 | if (!desc.files.length) {
|
160 | continue;
|
161 | }
|
162 | loader !== null && loader !== void 0 ? loader : (loader = await (0, load_translations_1.createTranslationLoader)());
|
163 | loadTranslations(locale, desc, context.workspaceRoot, loader, {
|
164 | warn(message) {
|
165 | context.logger.warn(message);
|
166 | },
|
167 | error(message) {
|
168 | throw new Error(message);
|
169 | },
|
170 | }, usedFormats, buildOptions.i18nDuplicateTranslation);
|
171 | if (usedFormats.size > 1 && tsConfig.options.enableI18nLegacyMessageIdFormat !== false) {
|
172 | // This limitation is only for legacy message id support (defaults to true as of 9.0)
|
173 | throw new Error('Localization currently only supports using one type of translation file format for the entire application.');
|
174 | }
|
175 | }
|
176 | // If inlining store the output in a temporary location to facilitate post-processing
|
177 | if (i18n.shouldInline) {
|
178 | // TODO: we should likely save these in the .angular directory in the next major version.
|
179 | // We'd need to do a migration to add the temp directory to gitignore.
|
180 | const tempPath = fs_1.default.mkdtempSync(path_1.default.join(fs_1.default.realpathSync(os_1.default.tmpdir()), 'angular-cli-i18n-'));
|
181 | buildOptions.outputPath = tempPath;
|
182 | process.on('exit', () => {
|
183 | try {
|
184 | fs_1.default.rmSync(tempPath, { force: true, recursive: true, maxRetries: 3 });
|
185 | }
|
186 | catch (_a) { }
|
187 | });
|
188 | }
|
189 | return { buildOptions, i18n };
|
190 | }
|
191 | exports.configureI18nBuild = configureI18nBuild;
|
192 | function findLocaleDataPath(locale, resolver) {
|
193 | // Remove private use subtags
|
194 | const scrubbedLocale = locale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
|
195 | try {
|
196 | return resolver(scrubbedLocale);
|
197 | }
|
198 | catch (_a) {
|
199 | // fallback to known existing en-US locale data as of 14.0
|
200 | return scrubbedLocale === 'en-US' ? findLocaleDataPath('en', resolver) : null;
|
201 | }
|
202 | }
|
203 | function loadTranslations(locale, desc, workspaceRoot, loader, logger, usedFormats, duplicateTranslation) {
|
204 | let translations = undefined;
|
205 | for (const file of desc.files) {
|
206 | const loadResult = loader(path_1.default.join(workspaceRoot, file.path));
|
207 | for (const diagnostics of loadResult.diagnostics.messages) {
|
208 | if (diagnostics.type === 'error') {
|
209 | logger.error(`Error parsing translation file '${file.path}': ${diagnostics.message}`);
|
210 | }
|
211 | else {
|
212 | logger.warn(`WARNING [${file.path}]: ${diagnostics.message}`);
|
213 | }
|
214 | }
|
215 | if (loadResult.locale !== undefined && loadResult.locale !== locale) {
|
216 | logger.warn(`WARNING [${file.path}]: File target locale ('${loadResult.locale}') does not match configured locale ('${locale}')`);
|
217 | }
|
218 | usedFormats === null || usedFormats === void 0 ? void 0 : usedFormats.add(loadResult.format);
|
219 | file.format = loadResult.format;
|
220 | file.integrity = loadResult.integrity;
|
221 | if (translations) {
|
222 | // Merge translations
|
223 | for (const [id, message] of Object.entries(loadResult.translations)) {
|
224 | if (translations[id] !== undefined) {
|
225 | const duplicateTranslationMessage = `[${file.path}]: Duplicate translations for message '${id}' when merging.`;
|
226 | switch (duplicateTranslation) {
|
227 | case schema_1.I18NTranslation.Ignore:
|
228 | break;
|
229 | case schema_1.I18NTranslation.Error:
|
230 | logger.error(`ERROR ${duplicateTranslationMessage}`);
|
231 | break;
|
232 | case schema_1.I18NTranslation.Warning:
|
233 | default:
|
234 | logger.warn(`WARNING ${duplicateTranslationMessage}`);
|
235 | break;
|
236 | }
|
237 | }
|
238 | translations[id] = message;
|
239 | }
|
240 | }
|
241 | else {
|
242 | // First or only translation file
|
243 | translations = loadResult.translations;
|
244 | }
|
245 | }
|
246 | desc.translation = translations;
|
247 | }
|
248 | exports.loadTranslations = loadTranslations;
|
249 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5ndWxhcl9kZXZraXQvYnVpbGRfYW5ndWxhci9zcmMvdXRpbHMvaTE4bi1vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7Ozs7OztBQUdILCtDQUE0QztBQUM1Qyw0Q0FBb0I7QUFDcEIsb0RBQTRCO0FBQzVCLDRDQUFvQjtBQUNwQixnREFBd0I7QUFDeEIsdURBQTZGO0FBRTdGLDBEQUFzRDtBQUN0RCwyREFBaUY7QUFFakY7O0dBRUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLGdDQUFnQyxDQUFDO0FBc0JqRSxTQUFTLDhCQUE4QixDQUNyQyxNQUFzQixFQUN0QixNQUFjLEVBQ2QsbUJBQTRCO0lBRTVCLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFO1FBQzlCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUNqQjtJQUVELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLE9BQU8sS0FBSyxRQUFRLENBQUMsRUFBRTtRQUNuRixPQUFPLE1BQWtCLENBQUM7S0FDM0I7SUFFRCxJQUFJLFlBQVksR0FBRyxxREFBcUQsTUFBTSxrQkFBa0IsQ0FBQztJQUNqRyxJQUFJLG1CQUFtQixFQUFFO1FBQ3ZCLFlBQVksSUFBSSxpREFBaUQsQ0FBQztLQUNuRTtTQUFNO1FBQ0wsWUFBWSxJQUFJLHdDQUF3QyxDQUFDO0tBQzFEO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNoQyxDQUFDO0FBRUQsU0FBZ0IsaUJBQWlCLENBQy9CLFFBQXlCLEVBQ3pCLE1BQTJCO0lBRTNCLElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FB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QUFZLEVBQUU7WUFDaEIscUJBQXFCO1lBQ3JCLEtBQUssTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDbkUsSUFBSSxZQUFZLENBQUMsRUFBRSxDQUFDLEtBQUssU0FBUyxFQUFFO29CQUNsQyxNQUFNLDJCQUEyQixHQUFHLElBQUksSUFBSSxDQUFDLElBQUksMENBQTBDLEVBQUUsaUJBQWlCLENBQUM7b0JBQy9HLFFBQVEsb0JBQW9CLEVBQUU7d0JBQzVCLEtBQUssd0JBQWUsQ0FBQyxNQUFNOzRCQUN6QixNQUFNO3dCQUNSLEtBQUssd0JBQWUsQ0FBQyxLQUFLOzRCQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDOzRCQUNyRCxNQUFNO3dCQUNSLEtBQUssd0JBQWUsQ0FBQyxPQUFPLENBQUM7d0JBQzdCOzRCQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVywyQkFBMkIsRUFBRSxDQUFDLENBQUM7NEJBQ3RELE1BQU07cUJBQ1Q7aUJBQ0Y7Z0JBQ0QsWUFBWSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQzthQUM1QjtTQUNGO2FBQU07WUFDTCxpQ0FBaUM7WUFDakMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUM7U0FDeEM7S0FDRjtJQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDO0FBQ2xDLENBQUM7QUF4REQsNENBd0RDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEJ1aWxkZXJDb250ZXh0IH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2FyY2hpdGVjdCc7XG5pbXBvcnQgeyBqc29uIH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2NvcmUnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBtb2R1bGUgZnJvbSAnbW9kdWxlJztcbmltcG9ydCBvcyBmcm9tICdvcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IFNjaGVtYSBhcyBCcm93c2VyQnVpbGRlclNjaGVtYSwgSTE4TlRyYW5zbGF0aW9uIH0gZnJvbSAnLi4vYnVpbGRlcnMvYnJvd3Nlci9zY2hlbWEnO1xuaW1wb3J0IHsgU2NoZW1hIGFzIFNlcnZlckJ1aWxkZXJTY2hlbWEgfSBmcm9tICcuLi9idWlsZGVycy9zZXJ2ZXIvc2NoZW1hJztcbmltcG9ydCB7IHJlYWRUc2NvbmZpZyB9IGZyb20gJy4uL3V0aWxzL3JlYWQtdHNjb25maWcnO1xuaW1wb3J0IHsgVHJhbnNsYXRpb25Mb2FkZXIsIGNyZWF0ZVRyYW5zbGF0aW9uTG9hZGVyIH0gZnJvbSAnLi9sb2FkLXRyYW5zbGF0aW9ucyc7XG5cbi8qKlxuICogVGhlIGJhc2UgbW9kdWxlIGxvY2F0aW9uIHVzZWQgdG8gc2VhcmNoIGZvciBsb2NhbGUgc3BlY2lmaWMgZGF0YS5cbiAqL1xuY29uc3QgTE9DQUxFX0RBVEFfQkFTRV9NT0RVTEUgPSAnQGFuZ3VsYXIvY29tbW9uL2xvY2FsZXMvZ2xvYmFsJztcblxuZXhwb3J0IGludGVyZmFjZSBMb2NhbGVEZXNjcmlwdGlvbiB7XG4gIGZpbGVzOiB7XG4gICAgcGF0aDogc3RyaW5nO1xuICAgIGludGVncml0eT86IHN0cmluZztcbiAgICBmb3JtYXQ/OiBzdHJpbmc7XG4gIH1bXTtcbiAgdHJhbnNsYXRpb24/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgZGF0YVBhdGg/OiBzdHJpbmc7XG4gIGJhc2VIcmVmPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEkxOG5PcHRpb25zIHtcbiAgaW5saW5lTG9jYWxlczogU2V0PHN0cmluZz47XG4gIHNvdXJjZUxvY2FsZTogc3RyaW5nO1xuICBsb2NhbGVzOiBSZWNvcmQ8c3RyaW5nLCBMb2NhbGVEZXNjcmlwdGlvbj47XG4gIGZsYXRPdXRwdXQ/OiBib29sZWFuO1xuICByZWFkb25seSBzaG91bGRJbmxpbmU6IGJvb2xlYW47XG4gIGhhc0RlZmluZWRTb3VyY2VMb2NhbGU/OiBib29sZWFuO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVUcmFuc2xhdGlvbkZpbGVPcHRpb24oXG4gIG9wdGlvbjoganNvbi5Kc29uVmFsdWUsXG4gIGxvY2FsZTogc3RyaW5nLFxuICBleHBlY3RPYmplY3RJbkVycm9yOiBib29sZWFuLFxuKTogc3RyaW5nW10ge1xuICBpZiAodHlwZW9mIG9wdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gW29wdGlvbl07XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb24pICYmIG9wdGlvbi5ldmVyeSgoZWxlbWVudCkgPT4gdHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnKSkge1xuICAgIHJldHVybiBvcHRpb24gYXMgc3RyaW5nW107XG4gIH1cblxuICBsZXQgZXJyb3JNZXNzYWdlID0gYFByb2plY3QgaTE4biBsb2NhbGVzIHRyYW5zbGF0aW9uIGZpZWxkIHZhbHVlIGZvciAnJHtsb2NhbGV9JyBpcyBtYWxmb3JtZWQuIGA7XG4gIGlmIChleHBlY3RPYmplY3RJbkVycm9yKSB7XG4gICAgZXJyb3JNZXNzYWdlICs9ICdFeHBlY3RlZCBhIHN0cmluZywgYXJyYXkgb2Ygc3RyaW5ncywgb3Igb2JqZWN0Lic7XG4gIH0gZWxzZSB7XG4gICAgZXJyb3JNZXNzYWdlICs9ICdFeHBlY3RlZCBhIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmdzLic7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUkxOG5PcHRpb25zKFxuICBtZXRhZGF0YToganNvbi5Kc29uT2JqZWN0LFxuICBpbmxpbmU/OiBib29sZWFuIHwgc3RyaW5nW10sXG4pOiBJMThuT3B0aW9ucyB7XG4gIGlmIChtZXRhZGF0YS5pMThuICE9PSB1bmRlZmluZWQgJiYgIWpzb24uaXNKc29uT2JqZWN0KG1ldGFkYXRhLmkxOG4pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQcm9qZWN0IGkxOG4gZmllbGQgaXMgbWFsZm9ybWVkLiBFeHBlY3RlZCBhbiBvYmplY3QuJyk7XG4gIH1cbiAgbWV0YWRhdGEgPSBtZXRhZGF0YS5pMThuIHx8IHt9O1xuXG4gIGNvbnN0IGkxOG46IEkxOG5PcHRpb25zID0ge1xuICAgIGlubGluZUxvY2FsZXM6IG5ldyBTZXQ8c3RyaW5nPigpLFxuICAgIC8vIGVuLVVTIGlzIHRoZSBkZWZhdWx0IGxvY2FsZSBhZGRlZCB0byBBbmd1bGFyIGFwcGxpY2F0aW9ucyAoaHR0cHM6Ly9hbmd1bGFyLmlvL2d1aWRlL2kxOG4jaTE4bi1waXBlcylcbiAgICBzb3VyY2VMb2NhbGU6ICdlbi1VUycsXG4gICAgbG9jYWxlczoge30sXG4gICAgZ2V0IHNob3VsZElubGluZSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmlubGluZUxvY2FsZXMuc2l6ZSA+IDA7XG4gICAgfSxcbiAgfTtcblxuICBsZXQgcmF3U291cmNlTG9jYWxlO1xuICBsZXQgcmF3U291cmNlTG9jYWxlQmFzZUhyZWY7XG4gIGlmIChqc29uLmlzSnNvbk9iamVjdChtZXRhZGF0YS5zb3VyY2VMb2NhbGUpKSB7XG4gICAgcmF3U291cmNlTG9jYWxlID0gbWV0YWRhdGEuc291cmNlTG9jYWxlLmNvZGU7XG4gICAgaWYgKFxuICAgICAgbWV0YWRhdGEuc291cmNlTG9jYWxlLmJhc2VIcmVmICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHR5cGVvZiBtZXRhZGF0YS5zb3VyY2VMb2NhbGUuYmFzZUhyZWYgIT09ICdzdHJpbmcnXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2plY3QgaTE4biBzb3VyY2VMb2NhbGUgYmFzZUhyZWYgZmllbGQgaXMgbWFsZm9ybWVkLiBFeHBlY3RlZCBhIHN0cmluZy4nKTtcbiAgICB9XG4gICAgcmF3U291cmNlTG9jYWxlQmFzZUhyZWYgPSBtZXRhZGF0YS5zb3VyY2VMb2NhbGUuYmFzZUhyZWY7XG4gIH0gZWxzZSB7XG4gICAgcmF3U291cmNlTG9jYWxlID0gbWV0YWRhdGEuc291cmNlTG9jYWxlO1xuICB9XG5cbiAgaWYgKHJhd1NvdXJjZUxvY2FsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiByYXdTb3VyY2VMb2NhbGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2plY3QgaTE4biBzb3VyY2VMb2NhbGUgZmllbGQgaXMgbWFsZm9ybWVkLiBFeHBlY3RlZCBhIHN0cmluZy4nKTtcbiAgICB9XG5cbiAgICBpMThuLnNvdXJjZUxvY2FsZSA9IHJhd1NvdXJjZUxvY2FsZTtcbiAgICBpMThuLmhhc0RlZmluZWRTb3VyY2VMb2NhbGUgPSB0cnVlO1xuICB9XG5cbiAgaTE4bi5sb2NhbGVzW2kxOG4uc291cmNlTG9jYWxlXSA9IHtcbiAgICBmaWxlczogW10sXG4gICAgYmFzZUhyZWY6IHJhd1NvdXJjZUxvY2FsZUJhc2VIcmVmLFxuICB9O1xuXG4gIGlmIChtZXRhZGF0YS5sb2NhbGVzICE9PSB1bmRlZmluZWQgJiYgIWpzb24uaXNKc29uT2JqZWN0KG1ldGFkYXRhLmxvY2FsZXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQcm9qZWN0IGkxOG4gbG9jYWxlcyBmaWVsZCBpcyBtYWxmb3JtZWQuIEV4cGVjdGVkIGFuIG9iamVjdC4nKTtcbiAgfSBlbHNlIGlmIChtZXRhZGF0YS5sb2NhbGVzKSB7XG4gICAgZm9yIChjb25zdCBbbG9jYWxlLCBvcHRpb25zXSBvZiBPYmplY3QuZW50cmllcyhtZXRhZGF0YS5sb2NhbGVzKSkge1xuICAgICAgbGV0IHRyYW5zbGF0aW9uRmlsZXM7XG4gICAgICBsZXQgYmFzZUhyZWY7XG4gICAgICBpZiAoanNvbi5pc0pzb25PYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgdHJhbnNsYXRpb25GaWxlcyA9IG5vcm1hbGl6ZVRyYW5zbGF0aW9uRmlsZU9wdGlvbihvcHRpb25zLnRyYW5zbGF0aW9uLCBsb2NhbGUsIGZhbHNlKTtcblxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuYmFzZUhyZWYgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgYmFzZUhyZWYgPSBvcHRpb25zLmJhc2VIcmVmO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmFuc2xhdGlvbkZpbGVzID0gbm9ybWFsaXplVHJhbnNsYXRpb25GaWxlT3B0aW9uKG9wdGlvbnMsIGxvY2FsZSwgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChsb2NhbGUgPT09IGkxOG4uc291cmNlTG9jYWxlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQW4gaTE4biBsb2NhbGUgKCcke2xvY2FsZX0nKSBjYW5ub3QgYm90aCBiZSBhIHNvdXJjZSBsb2NhbGUgYW5kIHByb3ZpZGUgYSB0cmFuc2xhdGlvbi5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpMThuLmxvY2FsZXNbbG9jYWxlXSA9IHtcbiAgICAgICAgZmlsZXM6IHRyYW5zbGF0aW9uRmlsZXMubWFwKChmaWxlKSA9PiAoeyBwYXRoOiBmaWxlIH0pKSxcbiAgICAgICAgYmFzZUhyZWYsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGlmIChpbmxpbmUgPT09IHRydWUpIHtcbiAgICBpMThuLmlubGluZUxvY2FsZXMuYWRkKGkxOG4uc291cmNlTG9jYWxlKTtcbiAgICBPYmplY3Qua2V5cyhpMThuLmxvY2FsZXMpLmZvckVhY2goKGxvY2FsZSkgPT4gaTE4bi5pbmxpbmVMb2NhbGVzLmFkZChsb2NhbGUpKTtcbiAgfSBlbHNlIGlmIChpbmxpbmUpIHtcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBpbmxpbmUpIHtcbiAgICAgIGlmICghaTE4bi5sb2NhbGVzW2xvY2FsZV0gJiYgaTE4bi5zb3VyY2VMb2NhbGUgIT09IGxvY2FsZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVlc3RlZCBsb2NhbGUgJyR7bG9jYWxlfScgaXMgbm90IGRlZmluZWQgZm9yIHRoZSBwcm9qZWN0LmApO1xuICAgICAgfVxuXG4gICAgICBpMThuLmlubGluZUxvY2FsZXMuYWRkKGxvY2FsZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGkxOG47XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb25maWd1cmVJMThuQnVpbGQ8VCBleHRlbmRzIEJyb3dzZXJCdWlsZGVyU2NoZW1hIHwgU2VydmVyQnVpbGRlclNjaGVtYT4oXG4gIGNvbnRleHQ6IEJ1aWxkZXJDb250ZXh0LFxuICBvcHRpb25zOiBULFxuKTogUHJvbWlzZTx7XG4gIGJ1aWxkT3B0aW9uczogVDtcbiAgaTE4bjogSTE4bk9wdGlvbnM7XG59PiB7XG4gIGlmICghY29udGV4dC50YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBidWlsZGVyIHJlcXVpcmVzIGEgdGFyZ2V0LicpO1xuICB9XG5cbiAgY29uc3QgYnVpbGRPcHRpb25zID0geyAuLi5vcHRpb25zIH07XG4gIGNvbnN0IHRzQ29uZmlnID0gYXdhaXQgcmVhZFRzY29uZmlnKGJ1aWxkT3B0aW9ucy50c0NvbmZpZywgY29udGV4dC53b3Jrc3BhY2VSb290KTtcbiAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBjb250ZXh0LmdldFByb2plY3RNZXRhZGF0YShjb250ZXh0LnRhcmdldCk7XG4gIGNvbnN0IGkxOG4gPSBjcmVhdGVJMThuT3B0aW9ucyhtZXRhZGF0YSwgYnVpbGRPcHRpb25zLmxvY2FsaXplKTtcblxuICAvLyBObyBhZGRpdGlvbmFsIHByb2Nlc3NpbmcgbmVlZGVkIGlmIG5vIGlubGluaW5nIHJlcXVlc3RlZCBhbmQgbm8gc291cmNlIGxvY2FsZSBkZWZpbmVkLlxuICBpZiAoIWkxOG4uc2hvdWxkSW5saW5lICYmICFpMThuLmhhc0RlZmluZWRTb3VyY2VMb2NhbGUpIHtcbiAgICByZXR1cm4geyBidWlsZE9wdGlvbnMsIGkxOG4gfTtcbiAgfVxuXG4gIGNvbnN0IHByb2plY3RSb290ID0gcGF0aC5qb2luKGNvbnRleHQud29ya3NwYWNlUm9vdCwgKG1ldGFkYXRhLnJvb3QgYXMgc3RyaW5nKSB8fCAnJyk7XG4gIC8vIFRoZSB0cmFpbGluZyBzbGFzaCBpcyByZXF1aXJlZCB0byBzaWduYWwgdGhhdCB0aGUgcGF0aCBpcyBhIGRpcmVjdG9yeSBhbmQgbm90IGEgZmlsZS5cbiAgY29uc3QgcHJvamVjdFJlcXVpcmUgPSBtb2R1bGUuY3JlYXRlUmVxdWlyZShwcm9qZWN0Um9vdCArICcvJyk7XG4gIGNvbnN0IGxvY2FsZVJlc29sdmVyID0gKGxvY2FsZTogc3RyaW5nKSA9PlxuICAgIHByb2plY3RSZXF1aXJlLnJlc29sdmUocGF0aC5qb2luKExPQ0FMRV9EQVRBX0JBU0VfTU9EVUxFLCBsb2NhbGUpKTtcblxuICAvLyBMb2FkIGxvY2FsZSBkYXRhIGFuZCB0cmFuc2xhdGlvbnMgKGlmIHByZXNlbnQpXG4gIGxldCBsb2FkZXI7XG4gIGNvbnN0IHVzZWRGb3JtYXRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgW2xvY2FsZSwgZGVzY10gb2YgT2JqZWN0LmVudHJpZXMoaTE4bi5sb2NhbGVzKSkge1xuICAgIGlmICghaTE4bi5pbmxpbmVMb2NhbGVzLmhhcyhsb2NhbGUpICYmIGxvY2FsZSAhPT0gaTE4bi5zb3VyY2VMb2NhbGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGxldCBsb2NhbGVEYXRhUGF0aCA9IGZpbmRMb2NhbGVEYXRhUGF0aChsb2NhbGUsIGxvY2FsZVJlc29sdmVyKTtcbiAgICBpZiAoIWxvY2FsZURhdGFQYXRoKSB7XG4gICAgICBjb25zdCBbZmlyc3RdID0gbG9jYWxlLnNwbGl0KCctJyk7XG4gICAgICBpZiAoZmlyc3QpIHtcbiAgICAgICAgbG9jYWxlRGF0YVBhdGggPSBmaW5kTG9jYWxlRGF0YVBhdGgoZmlyc3QudG9Mb3dlckNhc2UoKSwgbG9jYWxlUmVzb2x2ZXIpO1xuICAgICAgICBpZiAobG9jYWxlRGF0YVBhdGgpIHtcbiAgICAgICAgICBjb250ZXh0LmxvZ2dlci53YXJuKFxuICAgICAgICAgICAgYExvY2FsZSBkYXRhIGZvciAnJHtsb2NhbGV9JyBjYW5ub3QgYmUgZm91bmQuIFVzaW5nIGxvY2FsZSBkYXRhIGZvciAnJHtmaXJzdH0nLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWxvY2FsZURhdGFQYXRoKSB7XG4gICAgICBjb250ZXh0LmxvZ2dlci53YXJuKFxuICAgICAgICBgTG9jYWxlIGRhdGEgZm9yICcke2xvY2FsZX0nIGNhbm5vdCBiZSBmb3VuZC4gTm8gbG9jYWxlIGRhdGEgd2lsbCBiZSBpbmNsdWRlZCBmb3IgdGhpcyBsb2NhbGUuYCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlc2MuZGF0YVBhdGggPSBsb2NhbGVEYXRhUGF0aDtcbiAgICB9XG5cbiAgICBpZiAoIWRlc2MuZmlsZXMubGVuZ3RoKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBsb2FkZXIgPz89IGF3YWl0IGNyZWF0ZVRyYW5zbGF0aW9uTG9hZGVyKCk7XG5cbiAgICBsb2FkVHJhbnNsYXRpb25zKFxuICAgICAgbG9jYWxlLFxuICAgICAgZGVzYyxcbiAgICAgIGNvbnRleHQud29ya3NwYWNlUm9vdCxcbiAgICAgIGxvYWRlcixcbiAgICAgIHtcbiAgICAgICAgd2FybihtZXNzYWdlKSB7XG4gICAgICAgICAgY29udGV4dC5sb2dnZXIud2FybihtZXNzYWdlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IobWVzc2FnZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB1c2VkRm9ybWF0cyxcbiAgICAgIGJ1aWxkT3B0aW9ucy5pMThuRHVwbGljYXRlVHJhbnNsYXRpb24sXG4gICAgKTtcblxuICAgIGlmICh1c2VkRm9ybWF0cy5zaXplID4gMSAmJiB0c0NvbmZpZy5vcHRpb25zLmVuYWJsZUkxOG5MZWdhY3lNZXNzYWdlSWRGb3JtYXQgIT09IGZhbHNlKSB7XG4gICAgICAvLyBUaGlzIGxpbWl0YXRpb24gaXMgb25seSBmb3IgbGVnYWN5IG1lc3NhZ2UgaWQgc3VwcG9ydCAoZGVmYXVsdHMgdG8gdHJ1ZSBhcyBvZiA5LjApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdMb2NhbGl6YXRpb24gY3VycmVudGx5IG9ubHkgc3VwcG9ydHMgdXNpbmcgb25lIHR5cGUgb2YgdHJhbnNsYXRpb24gZmlsZSBmb3JtYXQgZm9yIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uJyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgaW5saW5pbmcgc3RvcmUgdGhlIG91dHB1dCBpbiBhIHRlbXBvcmFyeSBsb2NhdGlvbiB0byBmYWNpbGl0YXRlIHBvc3QtcHJvY2Vzc2luZ1xuICBpZiAoaTE4bi5zaG91bGRJbmxpbmUpIHtcbiAgICAvLyBUT0RPOiB3ZSBzaG91bGQgbGlrZWx5IHNhdmUgdGhlc2UgaW4gdGhlIC5hbmd1bGFyIGRpcmVjdG9yeSBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uLlxuICAgIC8vIFdlJ2QgbmVlZCB0byBkbyBhIG1pZ3JhdGlvbiB0byBhZGQgdGhlIHRlbXAgZGlyZWN0b3J5IHRvIGdpdGlnbm9yZS5cbiAgICBjb25zdCB0ZW1wUGF0aCA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihmcy5yZWFscGF0aFN5bmMob3MudG1wZGlyKCkpLCAnYW5ndWxhci1jbGktaTE4bi0nKSk7XG4gICAgYnVpbGRPcHRpb25zLm91dHB1dFBhdGggPSB0ZW1wUGF0aDtcblxuICAgIHByb2Nlc3Mub24oJ2V4aXQnLCAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBmcy5ybVN5bmModGVtcFBhdGgsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSwgbWF4UmV0cmllczogMyB9KTtcbiAgICAgIH0gY2F0Y2gge31cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB7IGJ1aWxkT3B0aW9ucywgaTE4biB9O1xufVxuXG5mdW5jdGlvbiBmaW5kTG9jYWxlRGF0YVBhdGgobG9jYWxlOiBzdHJpbmcsIHJlc29sdmVyOiAobG9jYWxlOiBzdHJpbmcpID0+IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAvLyBSZW1vdmUgcHJpdmF0ZSB1c2Ugc3VidGFnc1xuICBjb25zdCBzY3J1YmJlZExvY2FsZSA9IGxvY2FsZS5yZXBsYWNlKC8teCgtW2EtekEtWjAtOV17MSw4fSkrJC8sICcnKTtcblxuICB0cnkge1xuICAgIHJldHVybiByZXNvbHZlcihzY3J1YmJlZExvY2FsZSk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIGZhbGxiYWNrIHRvIGtub3duIGV4aXN0aW5nIGVuLVVTIGxvY2FsZSBkYXRhIGFzIG9mIDE0LjBcbiAgICByZXR1cm4gc2NydWJiZWRMb2NhbGUgPT09ICdlbi1VUycgPyBmaW5kTG9jYWxlRGF0YVBhdGgoJ2VuJywgcmVzb2x2ZXIpIDogbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZFRyYW5zbGF0aW9ucyhcbiAgbG9jYWxlOiBzdHJpbmcsXG4gIGRlc2M6IExvY2FsZURlc2NyaXB0aW9uLFxuICB3b3Jrc3BhY2VSb290OiBzdHJpbmcsXG4gIGxvYWRlcjogVHJhbnNsYXRpb25Mb2FkZXIsXG4gIGxvZ2dlcjogeyB3YXJuOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkOyBlcnJvcjogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCB9LFxuICB1c2VkRm9ybWF0cz86IFNldDxzdHJpbmc+LFxuICBkdXBsaWNhdGVUcmFuc2xhdGlvbj86IEkxOE5UcmFuc2xhdGlvbixcbikge1xuICBsZXQgdHJhbnNsYXRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgZm9yIChjb25zdCBmaWxlIG9mIGRlc2MuZmlsZXMpIHtcbiAgICBjb25zdCBsb2FkUmVzdWx0ID0gbG9hZGVyKHBhdGguam9pbih3b3Jrc3BhY2VSb290LCBmaWxlLnBhdGgpKTtcblxuICAgIGZvciAoY29uc3QgZGlhZ25vc3RpY3Mgb2YgbG9hZFJlc3VsdC5kaWFnbm9zdGljcy5tZXNzYWdlcykge1xuICAgICAgaWYgKGRpYWdub3N0aWNzLnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBwYXJzaW5nIHRyYW5zbGF0aW9uIGZpbGUgJyR7ZmlsZS5wYXRofSc6ICR7ZGlhZ25vc3RpY3MubWVzc2FnZX1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBXQVJOSU5HIFske2ZpbGUucGF0aH1dOiAke2RpYWdub3N0aWNzLm1lc3NhZ2V9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxvYWRSZXN1bHQubG9jYWxlICE9PSB1bmRlZmluZWQgJiYgbG9hZFJlc3VsdC5sb2NhbGUgIT09IGxvY2FsZSkge1xuICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgIGBXQVJOSU5HIFske2ZpbGUucGF0aH1dOiBGaWxlIHRhcmdldCBsb2NhbGUgKCcke2xvYWRSZXN1bHQubG9jYWxlfScpIGRvZXMgbm90IG1hdGNoIGNvbmZpZ3VyZWQgbG9jYWxlICgnJHtsb2NhbGV9JylgLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB1c2VkRm9ybWF0cz8uYWRkKGxvYWRSZXN1bHQuZm9ybWF0KTtcbiAgICBmaWxlLmZvcm1hdCA9IGxvYWRSZXN1bHQuZm9ybWF0O1xuICAgIGZpbGUuaW50ZWdyaXR5ID0gbG9hZFJlc3VsdC5pbnRlZ3JpdHk7XG5cbiAgICBpZiAodHJhbnNsYXRpb25zKSB7XG4gICAgICAvLyBNZXJnZSB0cmFuc2xhdGlvbnNcbiAgICAgIGZvciAoY29uc3QgW2lkLCBtZXNzYWdlXSBvZiBPYmplY3QuZW50cmllcyhsb2FkUmVzdWx0LnRyYW5zbGF0aW9ucykpIHtcbiAgICAgICAgaWYgKHRyYW5zbGF0aW9uc1tpZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZVRyYW5zbGF0aW9uTWVzc2FnZSA9IGBbJHtmaWxlLnBhdGh9XTogRHVwbGljYXRlIHRyYW5zbGF0aW9ucyBmb3IgbWVzc2FnZSAnJHtpZH0nIHdoZW4gbWVyZ2luZy5gO1xuICAgICAgICAgIHN3aXRjaCAoZHVwbGljYXRlVHJhbnNsYXRpb24pIHtcbiAgICAgICAgICAgIGNhc2UgSTE4TlRyYW5zbGF0aW9uLklnbm9yZTpcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEkxOE5UcmFuc2xhdGlvbi5FcnJvcjpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBFUlJPUiAke2R1cGxpY2F0ZVRyYW5zbGF0aW9uTWVzc2FnZX1gKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEkxOE5UcmFuc2xhdGlvbi5XYXJuaW5nOlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYFdBUk5JTkcgJHtkdXBsaWNhdGVUcmFuc2xhdGlvbk1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cmFuc2xhdGlvbnNbaWRdID0gbWVzc2FnZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRmlyc3Qgb3Igb25seSB0cmFuc2xhdGlvbiBmaWxlXG4gICAgICB0cmFuc2xhdGlvbnMgPSBsb2FkUmVzdWx0LnRyYW5zbGF0aW9ucztcbiAgICB9XG4gIH1cbiAgZGVzYy50cmFuc2xhdGlvbiA9IHRyYW5zbGF0aW9ucztcbn1cbiJdfQ== |
\ | No newline at end of file |