@angular/compiler
Version:
Angular - the compiler library
460 lines • 73.1 kB
JavaScript
import * as tslib_1 from "tslib";
/**
* @license
* Copyright Google Inc. 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
*/
import { CompileNgModuleMetadata, CompileSummaryKind } from '../compile_metadata';
import * as o from '../output/output_ast';
import { ValueTransformer, visitValue } from '../util';
import { StaticSymbol } from './static_symbol';
import { unwrapResolvedMetadata } from './static_symbol_resolver';
import { isLoweredSymbol, ngfactoryFilePath, summaryForJitFileName, summaryForJitName } from './util';
export function serializeSummaries(srcFileName, forJitCtx, summaryResolver, symbolResolver, symbols, types) {
var toJsonSerializer = new ToJsonSerializer(symbolResolver, summaryResolver, srcFileName);
// for symbols, we use everything except for the class metadata itself
// (we keep the statics though), as the class metadata is contained in the
// CompileTypeSummary.
symbols.forEach(function (resolvedSymbol) { return toJsonSerializer.addSummary({ symbol: resolvedSymbol.symbol, metadata: resolvedSymbol.metadata }); });
// Add type summaries.
types.forEach(function (_a) {
var summary = _a.summary, metadata = _a.metadata;
toJsonSerializer.addSummary({ symbol: summary.type.reference, metadata: undefined, type: summary });
});
var _a = toJsonSerializer.serialize(), json = _a.json, exportAs = _a.exportAs;
if (forJitCtx) {
var forJitSerializer_1 = new ForJitSerializer(forJitCtx, symbolResolver, summaryResolver);
types.forEach(function (_a) {
var summary = _a.summary, metadata = _a.metadata;
forJitSerializer_1.addSourceType(summary, metadata);
});
toJsonSerializer.unprocessedSymbolSummariesBySymbol.forEach(function (summary) {
if (summaryResolver.isLibraryFile(summary.symbol.filePath) && summary.type) {
forJitSerializer_1.addLibType(summary.type);
}
});
forJitSerializer_1.serialize(exportAs);
}
return { json: json, exportAs: exportAs };
}
export function deserializeSummaries(symbolCache, summaryResolver, libraryFileName, json) {
var deserializer = new FromJsonDeserializer(symbolCache, summaryResolver);
return deserializer.deserialize(libraryFileName, json);
}
export function createForJitStub(outputCtx, reference) {
return createSummaryForJitFunction(outputCtx, reference, o.NULL_EXPR);
}
function createSummaryForJitFunction(outputCtx, reference, value) {
var fnName = summaryForJitName(reference.name);
outputCtx.statements.push(o.fn([], [new o.ReturnStatement(value)], new o.ArrayType(o.DYNAMIC_TYPE)).toDeclStmt(fnName, [
o.StmtModifier.Final, o.StmtModifier.Exported
]));
}
var ToJsonSerializer = /** @class */ (function (_super) {
tslib_1.__extends(ToJsonSerializer, _super);
function ToJsonSerializer(symbolResolver, summaryResolver, srcFileName) {
var _this = _super.call(this) || this;
_this.symbolResolver = symbolResolver;
_this.summaryResolver = summaryResolver;
_this.srcFileName = srcFileName;
// Note: This only contains symbols without members.
_this.symbols = [];
_this.indexBySymbol = new Map();
_this.reexportedBy = new Map();
// This now contains a `__symbol: number` in the place of
// StaticSymbols, but otherwise has the same shape as the original objects.
_this.processedSummaryBySymbol = new Map();
_this.processedSummaries = [];
_this.unprocessedSymbolSummariesBySymbol = new Map();
_this.moduleName = symbolResolver.getKnownModuleName(srcFileName);
return _this;
}
ToJsonSerializer.prototype.addSummary = function (summary) {
var _this = this;
var unprocessedSummary = this.unprocessedSymbolSummariesBySymbol.get(summary.symbol);
var processedSummary = this.processedSummaryBySymbol.get(summary.symbol);
if (!unprocessedSummary) {
unprocessedSummary = { symbol: summary.symbol, metadata: undefined };
this.unprocessedSymbolSummariesBySymbol.set(summary.symbol, unprocessedSummary);
processedSummary = { symbol: this.processValue(summary.symbol, 0 /* None */) };
this.processedSummaries.push(processedSummary);
this.processedSummaryBySymbol.set(summary.symbol, processedSummary);
}
if (!unprocessedSummary.metadata && summary.metadata) {
var metadata_1 = summary.metadata || {};
if (metadata_1.__symbolic === 'class') {
// For classes, we keep everything except their class decorators.
// We need to keep e.g. the ctor args, method names, method decorators
// so that the class can be extended in another compilation unit.
// We don't keep the class decorators as
// 1) they refer to data
// that should not cause a rebuild of downstream compilation units
// (e.g. inline templates of @Component, or @NgModule.declarations)
// 2) their data is already captured in TypeSummaries, e.g. DirectiveSummary.
var clone_1 = {};
Object.keys(metadata_1).forEach(function (propName) {
if (propName !== 'decorators') {
clone_1[propName] = metadata_1[propName];
}
});
metadata_1 = clone_1;
}
else if (isCall(metadata_1)) {
if (!isFunctionCall(metadata_1) && !isMethodCallOnVariable(metadata_1)) {
// Don't store complex calls as we won't be able to simplify them anyways later on.
metadata_1 = {
__symbolic: 'error',
message: 'Complex function calls are not supported.',
};
}
}
// Note: We need to keep storing ctor calls for e.g.
// `export const x = new InjectionToken(...)`
unprocessedSummary.metadata = metadata_1;
processedSummary.metadata = this.processValue(metadata_1, 1 /* ResolveValue */);
if (metadata_1 instanceof StaticSymbol &&
this.summaryResolver.isLibraryFile(metadata_1.filePath)) {
var declarationSymbol = this.symbols[this.indexBySymbol.get(metadata_1)];
if (!isLoweredSymbol(declarationSymbol.name)) {
// Note: symbols that were introduced during codegen in the user file can have a reexport
// if a user used `export *`. However, we can't rely on this as tsickle will change
// `export *` into named exports, using only the information from the typechecker.
// As we introduce the new symbols after typecheck, Tsickle does not know about them,
// and omits them when expanding `export *`.
// So we have to keep reexporting these symbols manually via .ngfactory files.
this.reexportedBy.set(declarationSymbol, summary.symbol);
}
}
}
if (!unprocessedSummary.type && summary.type) {
unprocessedSummary.type = summary.type;
// Note: We don't add the summaries of all referenced symbols as for the ResolvedSymbols,
// as the type summaries already contain the transitive data that they require
// (in a minimal way).
processedSummary.type = this.processValue(summary.type, 0 /* None */);
// except for reexported directives / pipes, so we need to store
// their summaries explicitly.
if (summary.type.summaryKind === CompileSummaryKind.NgModule) {
var ngModuleSummary = summary.type;
ngModuleSummary.exportedDirectives.concat(ngModuleSummary.exportedPipes).forEach(function (id) {
var symbol = id.reference;
if (_this.summaryResolver.isLibraryFile(symbol.filePath) &&
!_this.unprocessedSymbolSummariesBySymbol.has(symbol)) {
var summary_1 = _this.summaryResolver.resolveSummary(symbol);
if (summary_1) {
_this.addSummary(summary_1);
}
}
});
}
}
};
ToJsonSerializer.prototype.serialize = function () {
var _this = this;
var exportAs = [];
var json = JSON.stringify({
moduleName: this.moduleName,
summaries: this.processedSummaries,
symbols: this.symbols.map(function (symbol, index) {
symbol.assertNoMembers();
var importAs = undefined;
if (_this.summaryResolver.isLibraryFile(symbol.filePath)) {
var reexportSymbol = _this.reexportedBy.get(symbol);
if (reexportSymbol) {
importAs = _this.indexBySymbol.get(reexportSymbol);
}
else {
var summary = _this.unprocessedSymbolSummariesBySymbol.get(symbol);
if (!summary || !summary.metadata || summary.metadata.__symbolic !== 'interface') {
importAs = symbol.name + "_" + index;
exportAs.push({ symbol: symbol, exportAs: importAs });
}
}
}
return {
__symbol: index,
name: symbol.name,
filePath: _this.summaryResolver.toSummaryFileName(symbol.filePath, _this.srcFileName),
importAs: importAs
};
})
});
return { json: json, exportAs: exportAs };
};
ToJsonSerializer.prototype.processValue = function (value, flags) {
return visitValue(value, this, flags);
};
ToJsonSerializer.prototype.visitOther = function (value, context) {
if (value instanceof StaticSymbol) {
var baseSymbol = this.symbolResolver.getStaticSymbol(value.filePath, value.name);
var index = this.visitStaticSymbol(baseSymbol, context);
return { __symbol: index, members: value.members };
}
};
/**
* Strip line and character numbers from ngsummaries.
* Emitting them causes white spaces changes to retrigger upstream
* recompilations in bazel.
* TODO: find out a way to have line and character numbers in errors without
* excessive recompilation in bazel.
*/
ToJsonSerializer.prototype.visitStringMap = function (map, context) {
if (map['__symbolic'] === 'resolved') {
return visitValue(map.symbol, this, context);
}
if (map['__symbolic'] === 'error') {
delete map['line'];
delete map['character'];
}
return _super.prototype.visitStringMap.call(this, map, context);
};
/**
* Returns null if the options.resolveValue is true, and the summary for the symbol
* resolved to a type or could not be resolved.
*/
ToJsonSerializer.prototype.visitStaticSymbol = function (baseSymbol, flags) {
var index = this.indexBySymbol.get(baseSymbol);
var summary = null;
if (flags & 1 /* ResolveValue */ &&
this.summaryResolver.isLibraryFile(baseSymbol.filePath)) {
if (this.unprocessedSymbolSummariesBySymbol.has(baseSymbol)) {
// the summary for this symbol was already added
// -> nothing to do.
return index;
}
summary = this.loadSummary(baseSymbol);
if (summary && summary.metadata instanceof StaticSymbol) {
// The summary is a reexport
index = this.visitStaticSymbol(summary.metadata, flags);
// reset the summary as it is just a reexport, so we don't want to store it.
summary = null;
}
}
else if (index != null) {
// Note: == on purpose to compare with undefined!
// No summary and the symbol is already added -> nothing to do.
return index;
}
// Note: == on purpose to compare with undefined!
if (index == null) {
index = this.symbols.length;
this.symbols.push(baseSymbol);
}
this.indexBySymbol.set(baseSymbol, index);
if (summary) {
this.addSummary(summary);
}
return index;
};
ToJsonSerializer.prototype.loadSummary = function (symbol) {
var summary = this.summaryResolver.resolveSummary(symbol);
if (!summary) {
// some symbols might originate from a plain typescript library
// that just exported .d.ts and .metadata.json files, i.e. where no summary
// files were created.
var resolvedSymbol = this.symbolResolver.resolveSymbol(symbol);
if (resolvedSymbol) {
summary = { symbol: resolvedSymbol.symbol, metadata: resolvedSymbol.metadata };
}
}
return summary;
};
return ToJsonSerializer;
}(ValueTransformer));
var ForJitSerializer = /** @class */ (function () {
function ForJitSerializer(outputCtx, symbolResolver, summaryResolver) {
this.outputCtx = outputCtx;
this.symbolResolver = symbolResolver;
this.summaryResolver = summaryResolver;
this.data = [];
}
ForJitSerializer.prototype.addSourceType = function (summary, metadata) {
this.data.push({ summary: summary, metadata: metadata, isLibrary: false });
};
ForJitSerializer.prototype.addLibType = function (summary) {
this.data.push({ summary: summary, metadata: null, isLibrary: true });
};
ForJitSerializer.prototype.serialize = function (exportAsArr) {
var _this = this;
var e_1, _a, e_2, _b, e_3, _c;
var exportAsBySymbol = new Map();
try {
for (var exportAsArr_1 = tslib_1.__values(exportAsArr), exportAsArr_1_1 = exportAsArr_1.next(); !exportAsArr_1_1.done; exportAsArr_1_1 = exportAsArr_1.next()) {
var _d = exportAsArr_1_1.value, symbol = _d.symbol, exportAs = _d.exportAs;
exportAsBySymbol.set(symbol, exportAs);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (exportAsArr_1_1 && !exportAsArr_1_1.done && (_a = exportAsArr_1.return)) _a.call(exportAsArr_1);
}
finally { if (e_1) throw e_1.error; }
}
var ngModuleSymbols = new Set();
try {
for (var _e = tslib_1.__values(this.data), _f = _e.next(); !_f.done; _f = _e.next()) {
var _g = _f.value, summary = _g.summary, metadata = _g.metadata, isLibrary = _g.isLibrary;
if (summary.summaryKind === CompileSummaryKind.NgModule) {
// collect the symbols that refer to NgModule classes.
// Note: we can't just rely on `summary.type.summaryKind` to determine this as
// we don't add the summaries of all referenced symbols when we serialize type summaries.
// See serializeSummaries for details.
ngModuleSymbols.add(summary.type.reference);
var modSummary = summary;
try {
for (var _h = tslib_1.__values(modSummary.modules), _j = _h.next(); !_j.done; _j = _h.next()) {
var mod = _j.value;
ngModuleSymbols.add(mod.reference);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
}
finally { if (e_3) throw e_3.error; }
}
}
if (!isLibrary) {
var fnName = summaryForJitName(summary.type.reference.name);
createSummaryForJitFunction(this.outputCtx, summary.type.reference, this.serializeSummaryWithDeps(summary, metadata));
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
}
finally { if (e_2) throw e_2.error; }
}
ngModuleSymbols.forEach(function (ngModuleSymbol) {
if (_this.summaryResolver.isLibraryFile(ngModuleSymbol.filePath)) {
var exportAs = exportAsBySymbol.get(ngModuleSymbol) || ngModuleSymbol.name;
var jitExportAsName = summaryForJitName(exportAs);
_this.outputCtx.statements.push(o.variable(jitExportAsName)
.set(_this.serializeSummaryRef(ngModuleSymbol))
.toDeclStmt(null, [o.StmtModifier.Exported]));
}
});
};
ForJitSerializer.prototype.serializeSummaryWithDeps = function (summary, metadata) {
var _this = this;
var expressions = [this.serializeSummary(summary)];
var providers = [];
if (metadata instanceof CompileNgModuleMetadata) {
expressions.push.apply(expressions, tslib_1.__spread(
// For directives / pipes, we only add the declared ones,
// and rely on transitively importing NgModules to get the transitive
// summaries.
metadata.declaredDirectives.concat(metadata.declaredPipes)
.map(function (type) { return type.reference; })
// For modules,
// we also add the summaries for modules
// from libraries.
// This is ok as we produce reexports for all transitive modules.
.concat(metadata.transitiveModule.modules.map(function (type) { return type.reference; })
.filter(function (ref) { return ref !== metadata.type.reference; }))
.map(function (ref) { return _this.serializeSummaryRef(ref); })));
// Note: We don't use `NgModuleSummary.providers`, as that one is transitive,
// and we already have transitive modules.
providers = metadata.providers;
}
else if (summary.summaryKind === CompileSummaryKind.Directive) {
var dirSummary = summary;
providers = dirSummary.providers.concat(dirSummary.viewProviders);
}
// Note: We can't just refer to the `ngsummary.ts` files for `useClass` providers (as we do for
// declaredDirectives / declaredPipes), as we allow
// providers without ctor arguments to skip the `@Injectable` decorator,
// i.e. we didn't generate .ngsummary.ts files for these.
expressions.push.apply(expressions, tslib_1.__spread(providers.filter(function (provider) { return !!provider.useClass; }).map(function (provider) { return _this.serializeSummary({
summaryKind: CompileSummaryKind.Injectable, type: provider.useClass
}); })));
return o.literalArr(expressions);
};
ForJitSerializer.prototype.serializeSummaryRef = function (typeSymbol) {
var jitImportedSymbol = this.symbolResolver.getStaticSymbol(summaryForJitFileName(typeSymbol.filePath), summaryForJitName(typeSymbol.name));
return this.outputCtx.importExpr(jitImportedSymbol);
};
ForJitSerializer.prototype.serializeSummary = function (data) {
var outputCtx = this.outputCtx;
var Transformer = /** @class */ (function () {
function Transformer() {
}
Transformer.prototype.visitArray = function (arr, context) {
var _this = this;
return o.literalArr(arr.map(function (entry) { return visitValue(entry, _this, context); }));
};
Transformer.prototype.visitStringMap = function (map, context) {
var _this = this;
return new o.LiteralMapExpr(Object.keys(map).map(function (key) { return new o.LiteralMapEntry(key, visitValue(map[key], _this, context), false); }));
};
Transformer.prototype.visitPrimitive = function (value, context) { return o.literal(value); };
Transformer.prototype.visitOther = function (value, context) {
if (value instanceof StaticSymbol) {
return outputCtx.importExpr(value);
}
else {
throw new Error("Illegal State: Encountered value " + value);
}
};
return Transformer;
}());
return visitValue(data, new Transformer(), null);
};
return ForJitSerializer;
}());
var FromJsonDeserializer = /** @class */ (function (_super) {
tslib_1.__extends(FromJsonDeserializer, _super);
function FromJsonDeserializer(symbolCache, summaryResolver) {
var _this = _super.call(this) || this;
_this.symbolCache = symbolCache;
_this.summaryResolver = summaryResolver;
return _this;
}
FromJsonDeserializer.prototype.deserialize = function (libraryFileName, json) {
var _this = this;
var data = JSON.parse(json);
var allImportAs = [];
this.symbols = data.symbols.map(function (serializedSymbol) { return _this.symbolCache.get(_this.summaryResolver.fromSummaryFileName(serializedSymbol.filePath, libraryFileName), serializedSymbol.name); });
data.symbols.forEach(function (serializedSymbol, index) {
var symbol = _this.symbols[index];
var importAs = serializedSymbol.importAs;
if (typeof importAs === 'number') {
allImportAs.push({ symbol: symbol, importAs: _this.symbols[importAs] });
}
else if (typeof importAs === 'string') {
allImportAs.push({ symbol: symbol, importAs: _this.symbolCache.get(ngfactoryFilePath(libraryFileName), importAs) });
}
});
var summaries = visitValue(data.summaries, this, null);
return { moduleName: data.moduleName, summaries: summaries, importAs: allImportAs };
};
FromJsonDeserializer.prototype.visitStringMap = function (map, context) {
if ('__symbol' in map) {
var baseSymbol = this.symbols[map['__symbol']];
var members = map['members'];
return members.length ? this.symbolCache.get(baseSymbol.filePath, baseSymbol.name, members) :
baseSymbol;
}
else {
return _super.prototype.visitStringMap.call(this, map, context);
}
};
return FromJsonDeserializer;
}(ValueTransformer));
function isCall(metadata) {
return metadata && metadata.__symbolic === 'call';
}
function isFunctionCall(metadata) {
return isCall(metadata) && unwrapResolvedMetadata(metadata.expression) instanceof StaticSymbol;
}
function isMethodCallOnVariable(metadata) {
return isCall(metadata) && metadata.expression && metadata.expression.__symbolic === 'select' &&
unwrapResolvedMetadata(metadata.expression.expression) instanceof StaticSymbol;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VtbWFyeV9zZXJpYWxpemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL2FvdC9zdW1tYXJ5X3NlcmlhbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRztBQUNILE9BQU8sRUFBb0QsdUJBQXVCLEVBQXdFLGtCQUFrQixFQUEwQyxNQUFNLHFCQUFxQixDQUFDO0FBQ2xQLE9BQU8sS0FBSyxDQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFFMUMsT0FBTyxFQUFnQixnQkFBZ0IsRUFBZ0IsVUFBVSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRWxGLE9BQU8sRUFBQyxZQUFZLEVBQW9CLE1BQU0saUJBQWlCLENBQUM7QUFDaEUsT0FBTyxFQUE2QyxzQkFBc0IsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQzVHLE9BQU8sRUFBQyxlQUFlLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFcEcsTUFBTSw2QkFDRixXQUFtQixFQUFFLFNBQStCLEVBQ3BELGVBQThDLEVBQUUsY0FBb0MsRUFDcEYsT0FBK0IsRUFBRSxLQUk5QjtJQUNMLElBQU0sZ0JBQWdCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsZUFBZSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRTVGLHNFQUFzRTtJQUN0RSwwRUFBMEU7SUFDMUUsc0JBQXNCO0lBQ3RCLE9BQU8sQ0FBQyxPQUFPLENBQ1gsVUFBQyxjQUFjLElBQUssT0FBQSxnQkFBZ0IsQ0FBQyxVQUFVLENBQzNDLEVBQUMsTUFBTSxFQUFFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUMsQ0FBQyxFQURuRCxDQUNtRCxDQUFDLENBQUM7SUFFN0Usc0JBQXNCO0lBQ3RCLEtBQUssQ0FBQyxPQUFPLENB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bnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHtDb21waWxlRGlyZWN0aXZlTWV0YWRhdGEsIENvbXBpbGVEaXJlY3RpdmVTdW1tYXJ5LCBDb21waWxlTmdNb2R1bGVNZXRhZGF0YSwgQ29tcGlsZU5nTW9kdWxlU3VtbWFyeSwgQ29tcGlsZVBpcGVNZXRhZGF0YSwgQ29tcGlsZVByb3ZpZGVyTWV0YWRhdGEsIENvbXBpbGVTdW1tYXJ5S2luZCwgQ29tcGlsZVR5cGVNZXRhZGF0YSwgQ29tcGlsZVR5cGVTdW1tYXJ5fSBmcm9tICcuLi9jb21waWxlX21ldGFkYXRhJztcbmltcG9ydCAqIGFzIG8gZnJvbSAnLi4vb3V0cHV0L291dHB1dF9hc3QnO1xuaW1wb3J0IHtTdW1tYXJ5LCBTdW1tYXJ5UmVzb2x2ZXJ9IGZyb20gJy4uL3N1bW1hcnlfcmVzb2x2ZXInO1xuaW1wb3J0IHtPdXRwdXRDb250ZXh0LCBWYWx1ZVRyYW5zZm9ybWVyLCBWYWx1ZVZpc2l0b3IsIHZpc2l0VmFsdWV9IGZyb20gJy4uL3V0aWwnO1xuXG5pbXBvcnQge1N0YXRpY1N5bWJvbCwgU3RhdGljU3ltYm9sQ2FjaGV9IGZyb20gJy4vc3RhdGljX3N5bWJvbCc7XG5pbXBvcnQge1Jlc29sdmVkU3RhdGljU3ltYm9sLCBTdGF0aWNTeW1ib2xSZXNvbHZlciwgdW53cmFwUmVzb2x2ZWRNZXRhZGF0YX0gZnJvbSAnLi9zdGF0aWNfc3ltYm9sX3Jlc29sdmVyJztcbmltcG9ydCB7aXNMb3dlcmVkU3ltYm9sLCBuZ2ZhY3RvcnlGaWxlUGF0aCwgc3VtbWFyeUZvckppdEZpbGVOYW1lLCBzdW1tYXJ5Rm9ySml0TmFtZX0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZVN1bW1hcmllcyhcbiAgICBzcmNGaWxlTmFtZTogc3RyaW5nLCBmb3JKaXRDdHg6IE91dHB1dENvbnRleHQgfCBudWxsLFxuICAgIHN1bW1hcnlSZXNvbHZlcjogU3VtbWFyeVJlc29sdmVyPFN0YXRpY1N5bWJvbD4sIHN5bWJvbFJlc29sdmVyOiBTdGF0aWNTeW1ib2xSZXNvbHZlcixcbiAgICBzeW1ib2xzOiBSZXNvbHZlZFN0YXRpY1N5bWJvbFtdLCB0eXBlczoge1xuICAgICAgc3VtbWFyeTogQ29tcGlsZVR5cGVTdW1tYXJ5LFxuICAgICAgbWV0YWRhdGE6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhIHwgQ29tcGlsZURpcmVjdGl2ZU1ldGFkYXRhIHwgQ29tcGlsZVBpcGVNZXRhZGF0YSB8XG4gICAgICAgICAgQ29tcGlsZVR5cGVNZXRhZGF0YVxuICAgIH1bXSk6IHtqc29uOiBzdHJpbmcsIGV4cG9ydEFzOiB7c3ltYm9sOiBTdGF0aWNTeW1ib2wsIGV4cG9ydEFzOiBzdHJpbmd9W119IHtcbiAgY29uc3QgdG9Kc29uU2VyaWFsaXplciA9IG5ldyBUb0pzb25TZXJpYWxpemVyKHN5bWJvbFJlc29sdmVyLCBzdW1tYXJ5UmVzb2x2ZXIsIHNyY0ZpbGVOYW1lKTtcblxuICAvLyBmb3Igc3ltYm9scywgd2UgdXNlIGV2ZXJ5dGhpbmcgZXhjZXB0IGZvciB0aGUgY2xhc3MgbWV0YWRhdGEgaXRzZWxmXG4gIC8vICh3ZSBrZWVwIHRoZSBzdGF0aWNzIHRob3VnaCksIGFzIHRoZSBjbGFzcyBtZXRhZGF0YSBpcyBjb250YWluZWQgaW4gdGhlXG4gIC8vIENvbXBpbGVUeXBlU3VtbWFyeS5cbiAgc3ltYm9scy5mb3JFYWNoKFxuICAgICAgKHJlc29sdmVkU3ltYm9sKSA9PiB0b0pzb25TZXJpYWxpemVyLmFkZFN1bW1hcnkoXG4gICAgICAgICAge3N5bWJvbDogcmVzb2x2ZWRTeW1ib2wuc3ltYm9sLCBtZXRhZGF0YTogcmVzb2x2ZWRTeW1ib2wubWV0YWRhdGF9KSk7XG5cbiAgLy8gQWRkIHR5cGUgc3VtbWFyaWVzLlxuICB0eXBlcy5mb3JFYWNoKCh7c3VtbWFyeSwgbWV0YWRhdGF9KSA9PiB7XG4gICAgdG9Kc29uU2VyaWFsaXplci5hZGRTdW1tYXJ5KFxuICAgICAgICB7c3ltYm9sOiBzdW1tYXJ5LnR5cGUucmVmZXJlbmNlLCBtZXRhZGF0YTogdW5kZWZpbmVkLCB0eXBlOiBzdW1tYXJ5fSk7XG4gIH0pO1xuICBjb25zdCB7anNvbiwgZXhwb3J0QXN9ID0gdG9Kc29uU2VyaWFsaXplci5zZXJpYWxpemUoKTtcbiAgaWYgKGZvckppdEN0eCkge1xuICAgIGNvbnN0IGZvckppdFNlcmlhbGl6ZXIgPSBuZXcgRm9ySml0U2VyaWFsaXplcihmb3JKaXRDdHgsIHN5bWJvbFJlc29sdmVyLCBzdW1tYXJ5UmVzb2x2ZXIpO1xuICAgIHR5cGVzLmZvckVhY2goKHtzdW1tYXJ5LCBtZXRhZGF0YX0pID0+IHsgZm9ySml0U2VyaWFsaXplci5hZGRTb3VyY2VUeXBlKHN1bW1hcnksIG1ldGFkYXRhKTsgfSk7XG4gICAgdG9Kc29uU2VyaWFsaXplci51bnByb2Nlc3NlZFN5bWJvbFN1bW1hcmllc0J5U3ltYm9sLmZvckVhY2goKHN1bW1hcnkpID0+IHtcbiAgICAgIGlmIChzdW1tYXJ5UmVzb2x2ZXIuaXNMaWJyYXJ5RmlsZShzdW1tYXJ5LnN5bWJvbC5maWxlUGF0aCkgJiYgc3VtbWFyeS50eXBlKSB7XG4gICAgICAgIGZvckppdFNlcmlhbGl6ZXIuYWRkTGliVHlwZShzdW1tYXJ5LnR5cGUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZvckppdFNlcmlhbGl6ZXIuc2VyaWFsaXplKGV4cG9ydEFzKTtcbiAgfVxuICByZXR1cm4ge2pzb24sIGV4cG9ydEFzfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplU3VtbWFyaWVzKFxuICAgIHN5bWJvbENhY2hlOiBTdGF0aWNTeW1ib2xDYWNoZSwgc3VtbWFyeVJlc29sdmVyOiBTdW1tYXJ5UmVzb2x2ZXI8U3RhdGljU3ltYm9sPixcbiAgICBsaWJyYXJ5RmlsZU5hbWU6IHN0cmluZywganNvbjogc3RyaW5nKToge1xuICBtb2R1bGVOYW1lOiBzdHJpbmcgfCBudWxsLFxuICBzdW1tYXJpZXM6IFN1bW1hcnk8U3RhdGljU3ltYm9sPltdLFxuICBpbXBvcnRBczoge3N5bWJvbDogU3RhdGljU3ltYm9sLCBpbXBvcnRBczogU3RhdGljU3ltYm9sfVtdXG59IHtcbiAgY29uc3QgZGVzZXJpYWxpemVyID0gbmV3IEZyb21Kc29uRGVzZXJpYWxpemVyKHN5bWJvbENhY2hlLCBzdW1tYXJ5UmVzb2x2ZXIpO1xuICByZXR1cm4gZGVzZXJpYWxpemVyLmRlc2VyaWFsaXplKGxpYnJhcnlGaWxlTmFtZSwganNvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGb3JKaXRTdHViKG91dHB1dEN0eDogT3V0cHV0Q29udGV4dCwgcmVmZXJlbmNlOiBTdGF0aWNTeW1ib2wpIHtcbiAgcmV0dXJuIGNyZWF0ZVN1bW1hcnlGb3JKaXRGdW5jdGlvbihvdXRwdXRDdHgsIHJlZmVyZW5jZSwgby5OVUxMX0VYUFIpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdW1tYXJ5Rm9ySml0RnVuY3Rpb24oXG4gICAgb3V0cHV0Q3R4OiBPdXRwdXRDb250ZXh0LCByZWZlcmVuY2U6IFN0YXRpY1N5bWJvbCwgdmFsdWU6IG8uRXhwcmVzc2lvbikge1xuICBjb25zdCBmbk5hbWUgPSBzdW1tYXJ5Rm9ySml0TmFtZShyZWZlcmVuY2UubmFtZSk7XG4gIG91dHB1dEN0eC5zdGF0ZW1lbnRzLnB1c2goXG4gICAgICBvLmZuKFtdLCBbbmV3IG8uUmV0dXJuU3RhdGVtZW50KHZhbHVlKV0sIG5ldyBvLkFycmF5VHlwZShvLkRZTkFNSUNfVFlQRSkpLnRvRGVjbFN0bXQoZm5OYW1lLCBbXG4gICAgICAgIG8uU3RtdE1vZGlmaWVyLkZpbmFsLCBvLlN0bXRNb2RpZmllci5FeHBvcnRlZFxuICAgICAgXSkpO1xufVxuXG5jb25zdCBlbnVtIFNlcmlhbGl6YXRpb25GbGFncyB7XG4gIE5vbmUgPSAwLFxuICBSZXNvbHZlVmFsdWUgPSAxLFxufVxuXG5jbGFzcyBUb0pzb25TZXJpYWxpemVyIGV4dGVuZHMgVmFsdWVUcmFuc2Zvcm1lciB7XG4gIC8vIE5vdGU6IFRoaXMgb25seSBjb250YWlucyBzeW1ib2xzIHdpdGhvdXQgbWVtYmVycy5cbiAgcHJpdmF0ZSBzeW1ib2xzOiBTdGF0aWNTeW1ib2xbXSA9IFtdO1xuICBwcml2YXRlIGluZGV4QnlTeW1ib2wgPSBuZXcgTWFwPFN0YXRpY1N5bWJvbCwgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlZXhwb3J0ZWRCeSA9IG5ldyBNYXA8U3RhdGljU3ltYm9sLCBTdGF0aWNTeW1ib2w+KCk7XG4gIC8vIFRoaXMgbm93IGNvbnRhaW5zIGEgYF9fc3ltYm9sOiBudW1iZXJgIGluIHRoZSBwbGFjZSBvZlxuICAvLyBTdGF0aWNTeW1ib2xzLCBidXQgb3RoZXJ3aXNlIGhhcyB0aGUgc2FtZSBzaGFwZSBhcyB0aGUgb3JpZ2luYWwgb2JqZWN0cy5cbiAgcHJpdmF0ZSBwcm9jZXNzZWRTdW1tYXJ5QnlTeW1ib2wgPSBuZXcgTWFwPFN0YXRpY1N5bWJvbCwgYW55PigpO1xuICBwcml2YXRlIHByb2Nlc3NlZFN1bW1hcmllczogYW55W10gPSBbXTtcbiAgcHJpdmF0ZSBtb2R1bGVOYW1lOiBzdHJpbmd8bnVsbDtcblxuICB1bnByb2Nlc3NlZFN5bWJvbFN1bW1hcmllc0J5U3ltYm9sID0gbmV3IE1hcDxTdGF0aWNTeW1ib2wsIFN1bW1hcnk8U3RhdGljU3ltYm9sPj4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgc3ltYm9sUmVzb2x2ZXI6IFN0YXRpY1N5bWJvbFJlc29sdmVyLFxuICAgICAgcHJpdmF0ZSBzdW1tYXJ5UmVzb2x2ZXI6IFN1bW1hcnlSZXNvbHZlc