UNPKG

@riddance/deploy

Version:

150 lines 27 kB
import { missing } from '@riddance/fetch'; import { createPublicKey, generateKeyPairSync, randomBytes } from 'node:crypto'; import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; export async function getGlue(path, prefix, resolver, gluePath) { const [packageJson, glueJson] = await Promise.all([ readFile(join(path, 'package.json'), 'utf-8'), readFile(gluePath ?? join(path, '..', 'glue', 'glue.json'), 'utf-8'), ]); const { name: service } = JSON.parse(packageJson); const glue = JSON.parse(glueJson); const { cors, env, secrets, ...provider } = glue.services[service] ?? {}; return { service, implementations: { ...glue.implementations, }, corsSites: cors ? (glue.websites[cors] ?? []) : [], env: resolveEnv(env ?? {}, secrets ?? {}, prefix, service, resolver), ...provider, }; } const own = Symbol(); const variables = [ { pattern: /\$ENV/gu, source: () => ({}), value: prefix => prefix, }, { pattern: /\$SERVICE/gu, source: () => ({}), value: (_prefix, service) => service, }, { pattern: /\$PRIVATE_KEY\(([^)]+)\)/gu, source: () => ({ environment: own }), value: (_prefix, service, [_, curve], key, env) => env[service]?.[key] ?? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion generateKeyPairSync('ec', { namedCurve: curve }) .privateKey.export({ type: 'sec1', format: 'pem' }) .toString() .split('\n') .slice(1, -2) .join(''), }, { pattern: /\$ASK\(([^)]*)\)/gu, source: () => ({ environment: own }), value: (_prefix, service, [_, hint], key, env, _url) => env[service]?.[key] ?? missing(`ASK implementation: ${hint}`), }, { pattern: /\$RANDOM\(([0-9]+)\)/gu, source: () => ({ environment: own }), value: (_prefix, service, [_, bits], key, env, _url) => env[service]?.[key] ?? randomBytes(Math.ceil(Number(bits) / 8)).toString('hex'), }, { pattern: /\$SAME_AS\(([^,]+),([^)]+)\)/gu, source: match => ({ environment: match[1] }), value: (_prefix, _service, [, service, key], _key, env, _url) => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion env[service]?.[key] ?? variableError( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion `Variable ${key} for ${service} not found. Has it been deployed?`), }, { pattern: /\$PUBLIC_KEY\(([^,]+),([^)]+)\)/gu, source: match => ({ environment: match[1] }), value: (_prefix, _service, [, service, key], _key, env) => createPublicKey(`-----BEGIN EC PRIVATE KEY-----\n${ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion env[service]?.[key] ?? variableError( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion `Private key for ${service} not found. Has it been deployed?`)}\n-----END EC PRIVATE KEY-----\n`) .export({ type: 'spki', format: 'pem' }) .toString() .split('\n') .slice(1, -2) .join(''), }, { pattern: /\$BASE_URL\(([^)]+)\)/gu, source: match => ({ baseUrl: match[1] }), value: (_prefix, _service, [_, service], _key, _env, url) => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion url[service] ?? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion variableError(`Base URL for ${service} not found. Has it been deployed?`), }, ]; function variableError(message) { throw new Error(message); } async function resolveEnv(clear, secrets, prefix, service, resolver) { const env = { ...clear, ...secrets, }; const referencedEnvironments = []; const referencedBaseUrls = []; const selfReferencing = []; for (const [key, value] of Object.entries(env)) { for (const v of variables) { for (const match of value.matchAll(v.pattern)) { const source = v.source(match); const sourceEnvName = source.environment === own ? service : source.environment; if (sourceEnvName && !referencedEnvironments.includes(sourceEnvName)) { if (source.environment === service) { selfReferencing.push({ key, v, match }); } else { referencedEnvironments.push(sourceEnvName); } } if (source.baseUrl && !referencedBaseUrls.includes(source.baseUrl)) { referencedBaseUrls.push(source.baseUrl); } } } } const [environments, baseUrls] = await Promise.all([ fetchEnvironments(prefix, referencedEnvironments, resolver), fetchBaseUrls(prefix, referencedBaseUrls, resolver), ]); for (const v of variables) { for (const [key, value] of Object.entries(env)) { env[key] = value.replaceAll(v.pattern, (substring, ...matches) => { if (selfReferencing.some(r => r.key === key && r.v === v && r.match[0] === substring)) { return substring; } return v.value(prefix, service, [substring, ...matches], key, environments, baseUrls); }); } } for (const ref of selfReferencing) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion env[ref.key] = env[ref.key].replaceAll(ref.v.pattern, (substring, ...matches) => { return ref.v.value(prefix, service, [substring, ...matches], ref.key, { [service]: env }, baseUrls); }); } return env; } async function fetchEnvironments(prefix, services, resolver) { return Object.fromEntries(await Promise.all(services.map(async (s) => [s, await resolver.getEnvironment(prefix, s)]))); } async function fetchBaseUrls(prefix, services, resolver) { return Object.fromEntries(await Promise.all(services.map(async (s) => [s, await resolver.getBaseUrl(prefix, s)]))); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2x1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdsdWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQy9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBT2hDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUFDLElBQVksRUFBRSxNQUFjLEVBQUUsUUFBa0IsRUFBRSxRQUFpQjtJQUM3RixNQUFNLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRSxPQUFPLENBQUM7UUFDN0MsUUFBUSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUUsT0FBTyxDQUFDO0tBQ3ZFLENBQUMsQ0FBQTtJQUNGLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQXFCLENBQUE7SUFDckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBa0IvQixDQUFBO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDeEUsT0FBTztRQUNILE9BQU87UUFDUCxlQUFlLEVBQUU7WUFDYixHQUFHLElBQUksQ0FBQyxlQUFlO1NBQzFCO1FBQ0QsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ2xELEdBQUcsRUFBRSxVQUFVLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxPQUFPLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDO1FBQ3BFLEdBQUcsUUFBUTtLQUNkLENBQUE7QUFDTCxDQUFDO0FBRUQsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUE7QUFrQnBCLE1BQU0sU0FBUyxHQUFlO0lBQzFCO1FBQ0ksT0FBTyxFQUFFLFNBQVM7UUFDbEIsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2xCLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU07S0FDMUI7SUFDRDtRQUNJLE9BQU8sRUFBRSxhQUFhO1FBQ3RCLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNsQixLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPO0tBQ3ZDO0lBQ0Q7UUFDSSxPQUFPLEVBQUUsNEJBQTRCO1FBQ3JDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ3BDLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQzlDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQztZQUNuQixvRUFBb0U7WUFDcEUsbUJBQW1CLENBQUMsSUFBSSxFQUFFLEVBQUUsVUFBVSxFQUFFLEtBQU0sRUFBRSxDQUFDO2lCQUM1QyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7aUJBQ2xELFFBQVEsRUFBRTtpQkFDVixLQUFLLENBQUMsSUFBSSxDQUFDO2lCQUNYLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ1osSUFBSSxDQUFDLEVBQUUsQ0FBQztLQUNwQjtJQUNEO1FBQ0ksT0FBTyxFQUFFLG9CQUFvQjtRQUM3QixNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNwQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FDbkQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLHVCQUF1QixJQUFJLEVBQUUsQ0FBQztLQUNwRTtJQUNEO1FBQ0ksT0FBTyxFQUFFLHdCQUF3QjtRQUNqQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNwQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FDbkQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztLQUN0RjtJQUNEO1FBQ0ksT0FBTyxFQUFFLGdDQUFnQztRQUN6QyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzVDLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQzVELG9FQUFvRTtRQUNwRSxHQUFHLENBQUMsT0FBUSxDQUFDLEVBQUUsQ0FBQyxHQUFJLENBQUM7WUFDckIsYUFBYTtZQUNULG9FQUFvRTtZQUNwRSxZQUFZLEdBQUksUUFBUSxPQUFRLG1DQUFtQyxDQUN0RTtLQUNSO0lBQ0Q7UUFDSSxPQUFPLEVBQUUsbUNBQW1DO1FBQzVDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUMsS0FBSyxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUN0RCxlQUFlLENBQ1gsbUNBQW1DO1FBQy9CLG9FQUFvRTtRQUNwRSxHQUFHLENBQUMsT0FBUSxDQUFDLEVBQUUsQ0FBQyxHQUFJLENBQUM7WUFDckIsYUFBYTtZQUNULG9FQUFvRTtZQUNwRSxtQkFBbUIsT0FBUSxtQ0FBbUMsQ0FFdEUsa0NBQWtDLENBQ3JDO2FBQ0ksTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7YUFDdkMsUUFBUSxFQUFFO2FBQ1YsS0FBSyxDQUFDLElBQUksQ0FBQzthQUNYLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDWixJQUFJLENBQUMsRUFBRSxDQUFDO0tBQ3BCO0lBQ0Q7UUFDSSxPQUFPLEVBQUUseUJBQXlCO1FBQ2xDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDeEMsS0FBSyxFQUFFLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQ3hELG9FQUFvRTtRQUNwRSxHQUFHLENBQUMsT0FBUSxDQUFDO1lBQ2Isb0VBQW9FO1lBQ3BFLGFBQWEsQ0FBQyxnQkFBZ0IsT0FBUSxtQ0FBbUMsQ0FBQztLQUNqRjtDQUNKLENBQUE7QUFFRCxTQUFTLGFBQWEsQ0FBQyxPQUFlO0lBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7QUFDNUIsQ0FBQztBQUVELEtBQUssVUFBVSxVQUFVLENBQ3JCLEtBQWdDLEVBQ2hDLE9BQWtDLEVBQ2xDLE1BQWMsRUFDZCxPQUFlLEVBQ2YsUUFBa0I7SUFFbEIsTUFBTSxHQUFHLEdBQUc7UUFDUixHQUFHLEtBQUs7UUFDUixHQUFHLE9BQU87S0FDYixDQUFBO0lBQ0QsTUFBTSxzQkFBc0IsR0FBYSxFQUFFLENBQUE7SUFDM0MsTUFBTSxrQkFBa0IsR0FBYSxFQUFFLENBQUE7SUFDdkMsTUFBTSxlQUFlLEdBQTRELEVBQUUsQ0FBQTtJQUNuRixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdDLEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7WUFDeEIsS0FBSyxNQUFNLEtBQUssSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO2dCQUM5QixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsV0FBVyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFBO2dCQUMvRSxJQUFJLGFBQWEsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO29CQUNuRSxJQUFJLE1BQU0sQ0FBQyxXQUFXLEtBQUssT0FBTyxFQUFFLENBQUM7d0JBQ2pDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUE7b0JBQzNDLENBQUM7eUJBQU0sQ0FBQzt3QkFDSixzQkFBc0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUE7b0JBQzlDLENBQUM7Z0JBQ0wsQ0FBQztnQkFDRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ2pFLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7Z0JBQzNDLENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFDRCxNQUFNLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUMvQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsc0JBQXNCLEVBQUUsUUFBUSxDQUFDO1FBQzNELGFBQWEsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxDQUFDO0tBQ3RELENBQUMsQ0FBQTtJQUNGLEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7UUFDeEIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsU0FBUyxFQUFFLEdBQUcsT0FBaUIsRUFBRSxFQUFFO2dCQUN2RSxJQUNJLGVBQWUsQ0FBQyxJQUFJLENBQ2hCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQzlELEVBQ0gsQ0FBQztvQkFDQyxPQUFPLFNBQVMsQ0FBQTtnQkFDcEIsQ0FBQztnQkFDRCxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQ1YsTUFBTSxFQUNOLE9BQU8sRUFDUCxDQUFDLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUN2QixHQUFHLEVBQ0gsWUFBWSxFQUNaLFFBQVEsQ0FDWCxDQUFBO1lBQ0wsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDaEMsb0VBQW9FO1FBQ3BFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQyxVQUFVLENBQ25DLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUNiLENBQUMsU0FBUyxFQUFFLEdBQUcsT0FBaUIsRUFBRSxFQUFFO1lBQ2hDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQ2QsTUFBTSxFQUNOLE9BQU8sRUFDUCxDQUFDLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUN2QixHQUFHLENBQUMsR0FBRyxFQUNQLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFDbEIsUUFBUSxDQUNYLENBQUE7UUFDTCxDQUFDLENBQ0osQ0FBQTtJQUNMLENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQTtBQUNkLENBQUM7QUFFRCxLQUFLLFVBQVUsaUJBQWlCLENBQUMsTUFBYyxFQUFFLFFBQWtCLEVBQUUsUUFBa0I7SUFDbkYsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUNyQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFVLENBQUMsQ0FDbEYsQ0FDSixDQUFBO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQUMsTUFBYyxFQUFFLFFBQWtCLEVBQUUsUUFBa0I7SUFDL0UsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUNyQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFVLENBQUMsQ0FDOUUsQ0FDSixDQUFBO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1pc3NpbmcgfSBmcm9tICdAcmlkZGFuY2UvZmV0Y2gnXG5pbXBvcnQgeyBjcmVhdGVQdWJsaWNLZXksIGdlbmVyYXRlS2V5UGFpclN5bmMsIHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nXG5pbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnXG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJ1xuXG5leHBvcnQgdHlwZSBSZXNvbHZlciA9IHtcbiAgICBnZXRFbnZpcm9ubWVudChwcmVmaXg6IHN0cmluZywgc2VydmljZTogc3RyaW5nKTogUHJvbWlzZTx7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9PlxuICAgIGdldEJhc2VVcmwocHJlZml4OiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPlxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0R2x1ZShwYXRoOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nLCByZXNvbHZlcjogUmVzb2x2ZXIsIGdsdWVQYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgW3BhY2thZ2VKc29uLCBnbHVlSnNvbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHJlYWRGaWxlKGpvaW4ocGF0aCwgJ3BhY2thZ2UuanNvbicpLCAndXRmLTgnKSxcbiAgICAgICAgcmVhZEZpbGUoZ2x1ZVBhdGggPz8gam9pbihwYXRoLCAnLi4nLCAnZ2x1ZScsICdnbHVlLmpzb24nKSwgJ3V0Zi04JyksXG4gICAgXSlcbiAgICBjb25zdCB7IG5hbWU6IHNlcnZpY2UgfSA9IEpTT04ucGFyc2UocGFja2FnZUpzb24pIGFzIHsgbmFtZTogc3RyaW5nIH1cbiAgICBjb25zdCBnbHVlID0gSlNPTi5wYXJzZShnbHVlSnNvbikgYXMge1xuICAgICAgICBpbXBsZW1lbnRhdGlvbnM6IHtcbiAgICAgICAgICAgIFtpbnRlcmZhY2VQYWNrYWdlOiBzdHJpbmddOiB7XG4gICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb246IHN0cmluZ1xuICAgICAgICAgICAgICAgIHZlcnNpb246IHN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHdlYnNpdGVzOiB7XG4gICAgICAgICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXVxuICAgICAgICB9XG4gICAgICAgIHNlcnZpY2VzOiB7XG4gICAgICAgICAgICBba2V5OiBzdHJpbmddOiB7XG4gICAgICAgICAgICAgICAgY29ycz86IHN0cmluZ1xuICAgICAgICAgICAgICAgIGVudjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfVxuICAgICAgICAgICAgICAgIHNlY3JldHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbiAgICAgICAgICAgICAgICBbcHJvdmlkZXI6IHN0cmluZ106IHVua25vd25cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHsgY29ycywgZW52LCBzZWNyZXRzLCAuLi5wcm92aWRlciB9ID0gZ2x1ZS5zZXJ2aWNlc1tzZXJ2aWNlXSA/PyB7fVxuICAgIHJldHVybiB7XG4gICAgICAgIHNlcnZpY2UsXG4gICAgICAgIGltcGxlbWVudGF0aW9uczoge1xuICAgICAgICAgICAgLi4uZ2x1ZS5pbXBsZW1lbnRhdGlvbnMsXG4gICAgICAgIH0sXG4gICAgICAgIGNvcnNTaXRlczogY29ycyA/IChnbHVlLndlYnNpdGVzW2NvcnNdID8/IFtdKSA6IFtdLFxuICAgICAgICBlbnY6IHJlc29sdmVFbnYoZW52ID8/IHt9LCBzZWNyZXRzID8/IHt9LCBwcmVmaXgsIHNlcnZpY2UsIHJlc29sdmVyKSxcbiAgICAgICAgLi4ucHJvdmlkZXIsXG4gICAgfVxufVxuXG5jb25zdCBvd24gPSBTeW1ib2woKVxuXG50eXBlIFZhcmlhYmxlID0ge1xuICAgIHBhdHRlcm46IFJlZ0V4cFxuICAgIHNvdXJjZTogKG1hdGNoOiBSZWdFeHBNYXRjaEFycmF5KSA9PiB7XG4gICAgICAgIGVudmlyb25tZW50Pzogc3RyaW5nIHwgdHlwZW9mIG93blxuICAgICAgICBiYXNlVXJsPzogc3RyaW5nXG4gICAgfVxuICAgIHZhbHVlOiAoXG4gICAgICAgIHByZWZpeDogc3RyaW5nLFxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgICAgIG1hdGNoOiBSZWdFeHBNYXRjaEFycmF5LFxuICAgICAgICBrZXk6IHN0cmluZyxcbiAgICAgICAgZW52aXJvbm1lbnRzOiB7IFtzZXJ2aWNlOiBzdHJpbmddOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IH0sXG4gICAgICAgIGJhc2VVcmxzOiB7IFtzZXJ2aWNlOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQgfSxcbiAgICApID0+IHN0cmluZ1xufVxuXG5jb25zdCB2YXJpYWJsZXM6IFZhcmlhYmxlW10gPSBbXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkRU5WL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7fSksXG4gICAgICAgIHZhbHVlOiBwcmVmaXggPT4gcHJlZml4LFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkU0VSVklDRS9ndSxcbiAgICAgICAgc291cmNlOiAoKSA9PiAoe30pLFxuICAgICAgICB2YWx1ZTogKF9wcmVmaXgsIHNlcnZpY2UpID0+IHNlcnZpY2UsXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRQUklWQVRFX0tFWVxcKChbXildKylcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogKCkgPT4gKHsgZW52aXJvbm1lbnQ6IG93biB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBzZXJ2aWNlLCBbXywgY3VydmVdLCBrZXksIGVudikgPT5cbiAgICAgICAgICAgIGVudltzZXJ2aWNlXT8uW2tleV0gPz9cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICBnZW5lcmF0ZUtleVBhaXJTeW5jKCdlYycsIHsgbmFtZWRDdXJ2ZTogY3VydmUhIH0pXG4gICAgICAgICAgICAgICAgLnByaXZhdGVLZXkuZXhwb3J0KHsgdHlwZTogJ3NlYzEnLCBmb3JtYXQ6ICdwZW0nIH0pXG4gICAgICAgICAgICAgICAgLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgICAgICAgLnNsaWNlKDEsIC0yKVxuICAgICAgICAgICAgICAgIC5qb2luKCcnKSxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJEFTS1xcKChbXildKilcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogKCkgPT4gKHsgZW52aXJvbm1lbnQ6IG93biB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBzZXJ2aWNlLCBbXywgaGludF0sIGtleSwgZW52LCBfdXJsKSA9PlxuICAgICAgICAgICAgZW52W3NlcnZpY2VdPy5ba2V5XSA/PyBtaXNzaW5nKGBBU0sgaW1wbGVtZW50YXRpb246ICR7aGludH1gKSxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJFJBTkRPTVxcKChbMC05XSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7IGVudmlyb25tZW50OiBvd24gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgc2VydmljZSwgW18sIGJpdHNdLCBrZXksIGVudiwgX3VybCkgPT5cbiAgICAgICAgICAgIGVudltzZXJ2aWNlXT8uW2tleV0gPz8gcmFuZG9tQnl0ZXMoTWF0aC5jZWlsKE51bWJlcihiaXRzKSAvIDgpKS50b1N0cmluZygnaGV4JyksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRTQU1FX0FTXFwoKFteLF0rKSwoW14pXSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6IG1hdGNoID0+ICh7IGVudmlyb25tZW50OiBtYXRjaFsxXSB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBfc2VydmljZSwgWywgc2VydmljZSwga2V5XSwgX2tleSwgZW52LCBfdXJsKSA9PlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIGVudltzZXJ2aWNlIV0/LltrZXkhXSA/P1xuICAgICAgICAgICAgdmFyaWFibGVFcnJvcihcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgIGBWYXJpYWJsZSAke2tleSF9IGZvciAke3NlcnZpY2UhfSBub3QgZm91bmQuIEhhcyBpdCBiZWVuIGRlcGxveWVkP2AsXG4gICAgICAgICAgICApLFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkUFVCTElDX0tFWVxcKChbXixdKyksKFteKV0rKVxcKS9ndSxcbiAgICAgICAgc291cmNlOiBtYXRjaCA9PiAoeyBlbnZpcm9ubWVudDogbWF0Y2hbMV0gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgX3NlcnZpY2UsIFssIHNlcnZpY2UsIGtleV0sIF9rZXksIGVudikgPT5cbiAgICAgICAgICAgIGNyZWF0ZVB1YmxpY0tleShcbiAgICAgICAgICAgICAgICBgLS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tXFxuJHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgICAgICAgICAgZW52W3NlcnZpY2UhXT8uW2tleSFdID8/XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgYFByaXZhdGUga2V5IGZvciAke3NlcnZpY2UhfSBub3QgZm91bmQuIEhhcyBpdCBiZWVuIGRlcGxveWVkP2AsXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XFxuLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLVxcbmAsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLmV4cG9ydCh7IHR5cGU6ICdzcGtpJywgZm9ybWF0OiAncGVtJyB9KVxuICAgICAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgICAgIC5zbGljZSgxLCAtMilcbiAgICAgICAgICAgICAgICAuam9pbignJyksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRCQVNFX1VSTFxcKChbXildKylcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogbWF0Y2ggPT4gKHsgYmFzZVVybDogbWF0Y2hbMV0gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgX3NlcnZpY2UsIFtfLCBzZXJ2aWNlXSwgX2tleSwgX2VudiwgdXJsKSA9PlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHVybFtzZXJ2aWNlIV0gPz9cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB2YXJpYWJsZUVycm9yKGBCYXNlIFVSTCBmb3IgJHtzZXJ2aWNlIX0gbm90IGZvdW5kLiBIYXMgaXQgYmVlbiBkZXBsb3llZD9gKSxcbiAgICB9LFxuXVxuXG5mdW5jdGlvbiB2YXJpYWJsZUVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IG5ldmVyIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUVudihcbiAgICBjbGVhcjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgICBzZWNyZXRzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICByZXNvbHZlcjogUmVzb2x2ZXIsXG4pIHtcbiAgICBjb25zdCBlbnYgPSB7XG4gICAgICAgIC4uLmNsZWFyLFxuICAgICAgICAuLi5zZWNyZXRzLFxuICAgIH1cbiAgICBjb25zdCByZWZlcmVuY2VkRW52aXJvbm1lbnRzOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3QgcmVmZXJlbmNlZEJhc2VVcmxzOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3Qgc2VsZlJlZmVyZW5jaW5nOiB7IGtleTogc3RyaW5nOyB2OiBWYXJpYWJsZTsgbWF0Y2g6IFJlZ0V4cE1hdGNoQXJyYXkgfVtdID0gW11cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgdmFsdWUubWF0Y2hBbGwodi5wYXR0ZXJuKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHYuc291cmNlKG1hdGNoKVxuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVudk5hbWUgPSBzb3VyY2UuZW52aXJvbm1lbnQgPT09IG93biA/IHNlcnZpY2UgOiBzb3VyY2UuZW52aXJvbm1lbnRcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlRW52TmFtZSAmJiAhcmVmZXJlbmNlZEVudmlyb25tZW50cy5pbmNsdWRlcyhzb3VyY2VFbnZOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmVudmlyb25tZW50ID09PSBzZXJ2aWNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmUmVmZXJlbmNpbmcucHVzaCh7IGtleSwgdiwgbWF0Y2ggfSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZWRFbnZpcm9ubWVudHMucHVzaChzb3VyY2VFbnZOYW1lKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuYmFzZVVybCAmJiAhcmVmZXJlbmNlZEJhc2VVcmxzLmluY2x1ZGVzKHNvdXJjZS5iYXNlVXJsKSkge1xuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VkQmFzZVVybHMucHVzaChzb3VyY2UuYmFzZVVybClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgW2Vudmlyb25tZW50cywgYmFzZVVybHNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBmZXRjaEVudmlyb25tZW50cyhwcmVmaXgsIHJlZmVyZW5jZWRFbnZpcm9ubWVudHMsIHJlc29sdmVyKSxcbiAgICAgICAgZmV0Y2hCYXNlVXJscyhwcmVmaXgsIHJlZmVyZW5jZWRCYXNlVXJscywgcmVzb2x2ZXIpLFxuICAgIF0pXG4gICAgZm9yIChjb25zdCB2IG9mIHZhcmlhYmxlcykge1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICAgICAgICBlbnZba2V5XSA9IHZhbHVlLnJlcGxhY2VBbGwodi5wYXR0ZXJuLCAoc3Vic3RyaW5nLCAuLi5tYXRjaGVzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgc2VsZlJlZmVyZW5jaW5nLnNvbWUoXG4gICAgICAgICAgICAgICAgICAgICAgICByID0+IHIua2V5ID09PSBrZXkgJiYgci52ID09PSB2ICYmIHIubWF0Y2hbMF0gPT09IHN1YnN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyaW5nXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB2LnZhbHVlKFxuICAgICAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIHNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgIFtzdWJzdHJpbmcsIC4uLm1hdGNoZXNdLFxuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50cyxcbiAgICAgICAgICAgICAgICAgICAgYmFzZVVybHMsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVmIG9mIHNlbGZSZWZlcmVuY2luZykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICBlbnZbcmVmLmtleV0gPSBlbnZbcmVmLmtleV0hLnJlcGxhY2VBbGwoXG4gICAgICAgICAgICByZWYudi5wYXR0ZXJuLFxuICAgICAgICAgICAgKHN1YnN0cmluZywgLi4ubWF0Y2hlczogc3RyaW5nW10pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVmLnYudmFsdWUoXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCxcbiAgICAgICAgICAgICAgICAgICAgc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgW3N1YnN0cmluZywgLi4ubWF0Y2hlc10sXG4gICAgICAgICAgICAgICAgICAgIHJlZi5rZXksXG4gICAgICAgICAgICAgICAgICAgIHsgW3NlcnZpY2VdOiBlbnYgfSxcbiAgICAgICAgICAgICAgICAgICAgYmFzZVVybHMsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKVxuICAgIH1cblxuICAgIHJldHVybiBlbnZcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hFbnZpcm9ubWVudHMocHJlZml4OiBzdHJpbmcsIHNlcnZpY2VzOiBzdHJpbmdbXSwgcmVzb2x2ZXI6IFJlc29sdmVyKSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBzZXJ2aWNlcy5tYXAoYXN5bmMgcyA9PiBbcywgYXdhaXQgcmVzb2x2ZXIuZ2V0RW52aXJvbm1lbnQocHJlZml4LCBzKV0gYXMgY29uc3QpLFxuICAgICAgICApLFxuICAgIClcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hCYXNlVXJscyhwcmVmaXg6IHN0cmluZywgc2VydmljZXM6IHN0cmluZ1tdLCByZXNvbHZlcjogUmVzb2x2ZXIpIHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIHNlcnZpY2VzLm1hcChhc3luYyBzID0+IFtzLCBhd2FpdCByZXNvbHZlci5nZXRCYXNlVXJsKHByZWZpeCwgcyldIGFzIGNvbnN0KSxcbiAgICAgICAgKSxcbiAgICApXG59XG4iXX0=