import * as o from '../output/output_ast'; import { Identifiers as R3 } from '../render3/r3_identifiers'; import { typeWithParameters } from './util'; export var R3FactoryDelegateType; (function (R3FactoryDelegateType) { R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class"; R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function"; })(R3FactoryDelegateType || (R3FactoryDelegateType = {})); export var FactoryTarget; (function (FactoryTarget) { FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive"; FactoryTarget[FactoryTarget["Component"] = 1] = "Component"; FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable"; FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe"; FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule"; })(FactoryTarget || (FactoryTarget = {})); /** * Construct a factory function expression for the given `R3FactoryMetadata`. */ export function compileFactoryFunction(meta) { const t = o.variable('t'); let baseFactoryVar = null; // The type to instantiate via constructor invocation. If there is no delegated factory, meaning // this type is always created by constructor invocation, then this is the type-to-create // parameter provided by the user (t) if specified, or the current type if not. If there is a // delegated factory (which is used to create the current type) then this is only the type-to- // create parameter (t). const typeForCtor = !isDelegatedFactoryMetadata(meta) ? new o.BinaryOperatorExpr(o.BinaryOperator.Or, t, meta.type.value) : t; let ctorExpr = null; if (meta.deps !== null) { // There is a constructor (either explicitly or implicitly defined). if (meta.deps !== 'invalid') { ctorExpr = new o.InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target)); } } else { // There is no constructor, use the base class' factory to construct typeForCtor. baseFactoryVar = o.variable(`ɵ${meta.name}_BaseFactory`); ctorExpr = baseFactoryVar.callFn([typeForCtor]); } const body = []; let retExpr = null; function makeConditionalFactory(nonCtorExpr) { const r = o.variable('r'); body.push(r.set(o.NULL_EXPR).toDeclStmt()); const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() : o.importExpr(R3.invalidFactory).callFn([]).toStmt(); body.push(o.ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()])); return r; } if (isDelegatedFactoryMetadata(meta)) { // This type is created with a delegated factory. If a type parameter is not specified, call // the factory instead. const delegateArgs = injectDependencies(meta.delegateDeps, meta.target); // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType. const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ? o.InstantiateExpr : o.InvokeFunctionExpr)(meta.delegate, delegateArgs); retExpr = makeConditionalFactory(factoryExpr); } else if (isExpressionFactoryMetadata(meta)) { // TODO(alxhub): decide whether to lower the value here or in the caller retExpr = makeConditionalFactory(meta.expression); } else { retExpr = ctorExpr; } if (retExpr === null) { // The expression cannot be formed so render an `ɵɵinvalidFactory()` call. body.push(o.importExpr(R3.invalidFactory).callFn([]).toStmt()); } else if (baseFactoryVar !== null) { // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it. const getInheritedFactoryCall = o.importExpr(R3.getInheritedFactory).callFn([meta.type.value]); // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))` const baseFactory = new o.BinaryOperatorExpr(o.BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall)); body.push(new o.ReturnStatement(baseFactory.callFn([typeForCtor]))); } else { // This is straightforward factory, just return it. body.push(new o.ReturnStatement(retExpr)); } let factoryFn = o.fn([new o.FnParam('t', o.DYNAMIC_TYPE)], body, o.INFERRED_TYPE, undefined, `${meta.name}_Factory`); if (baseFactoryVar !== null) { // There is a base factory variable so wrap its declaration along with the factory function into // an IIFE. factoryFn = o.fn([], [ new o.DeclareVarStmt(baseFactoryVar.name), new o.ReturnStatement(factoryFn) ]).callFn([], /* sourceSpan */ undefined, /* pure */ true); } return { expression: factoryFn, statements: [], type: createFactoryType(meta), }; } export function createFactoryType(meta) { const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : o.NONE_TYPE; return o.expressionType(o.importExpr(R3.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType])); } function injectDependencies(deps, target) { return deps.map((dep, index) => compileInjectDependency(dep, target, index)); } function compileInjectDependency(dep, target, index) { // Interpret the dependency according to its resolved type. if (dep.token === null) { return o.importExpr(R3.invalidFactoryDep).callFn([o.literal(index)]); } else if (dep.attributeNameType === null) { // Build up the injection flags according to the metadata. const flags = 0 /* InjectFlags.Default */ | (dep.self ? 2 /* InjectFlags.Self */ : 0) | (dep.skipSelf ? 4 /* InjectFlags.SkipSelf */ : 0) | (dep.host ? 1 /* InjectFlags.Host */ : 0) | (dep.optional ? 8 /* InjectFlags.Optional */ : 0) | (target === FactoryTarget.Pipe ? 16 /* InjectFlags.ForPipe */ : 0); // If this dependency is optional or otherwise has non-default flags, then additional // parameters describing how to inject the dependency must be passed to the inject function // that's being used. let flagsParam = (flags !== 0 /* InjectFlags.Default */ || dep.optional) ? o.literal(flags) : null; // Build up the arguments to the injectFn call. const injectArgs = [dep.token]; if (flagsParam) { injectArgs.push(flagsParam); } const injectFn = getInjectFn(target); return o.importExpr(injectFn).callFn(injectArgs); } else { // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()` // type dependency. For the generated JS we still want to use the `dep.token` value in case the // name given for the attribute is not a string literal. For example given `@Attribute(foo())`, // we want to generate `ɵɵinjectAttribute(foo())`. // // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate // typings. return o.importExpr(R3.injectAttribute).callFn([dep.token]); } } function createCtorDepsType(deps) { let hasTypes = false; const attributeTypes = deps.map(dep => { const type = createCtorDepType(dep); if (type !== null) { hasTypes = true; return type; } else { return o.literal(null); } }); if (hasTypes) { return o.expressionType(o.literalArr(attributeTypes)); } else { return o.NONE_TYPE; } } function createCtorDepType(dep) { const entries = []; if (dep.attributeNameType !== null) { entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false }); } if (dep.optional) { entries.push({ key: 'optional', value: o.literal(true), quoted: false }); } if (dep.host) { entries.push({ key: 'host', value: o.literal(true), quoted: false }); } if (dep.self) { entries.push({ key: 'self', value: o.literal(true), quoted: false }); } if (dep.skipSelf) { entries.push({ key: 'skipSelf', value: o.literal(true), quoted: false }); } return entries.length > 0 ? o.literalMap(entries) : null; } export function isDelegatedFactoryMetadata(meta) { return meta.delegateType !== undefined; } export function isExpressionFactoryMetadata(meta) { return meta.expression !== undefined; } function getInjectFn(target) { switch (target) { case FactoryTarget.Component: case FactoryTarget.Directive: case FactoryTarget.Pipe: return R3.directiveInject; case FactoryTarget.NgModule: case FactoryTarget.Injectable: default: return R3.inject; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfZmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9yZW5kZXIzL3IzX2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUEsT0FBTyxLQUFLLENBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxJQUFJLEVBQUUsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRTVELE9BQU8sRUFBb0Msa0JBQWtCLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFvQzdFLE1BQU0sQ0FBTixJQUFZLHFCQUdYO0FBSEQsV0FBWSxxQkFBcUI7SUFDL0IsbUVBQVMsQ0FBQTtJQUNULHlFQUFZLENBQUE7QUFDZCxDQUFDLEVBSFcscUJBQXFCLEtBQXJCLHFCQUFxQixRQUdoQztBQWVELE1BQU0sQ0FBTixJQUFZLGFBTVg7QUFORCxXQUFZLGFBQWE7SUFDdkIsMkRBQWEsQ0FBQTtJQUNiLDJEQUFhLENBQUE7SUFDYiw2REFBYyxDQUFBO0lBQ2QsaURBQVEsQ0FBQTtJQUNSLHlEQUFZLENBQUE7QUFDZCxDQUFDLEVBTlcsYUFBYSxLQUFiLGFBQWEsUUFNeEI7QUFxQ0Q7O0dBRUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsSUFBdUI7SUFDNUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMxQixJQUFJLGNBQWMsR0FBdUIsSUFBSSxDQUFDO0lBRTlDLGdHQUFnRztJQUNoRyx5RkFBeUY7SUFDekYsNkZBQTZGO0lBQzdGLDhGQUE4RjtJQUM5Rix3QkFBd0I7SUFDeEIsTUFBTSxXQUFXLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENB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QUFDLE1BQXFCO0lBQ3hDLFFBQVEsTUFBTSxFQUFFO1FBQ2QsS0FBSyxhQUFhLENBQUMsU0FBUyxDQUFDO1FBQzdCLEtBQUssYUFBYSxDQUFDLFNBQVMsQ0FBQztRQUM3QixLQUFLLGFBQWEsQ0FBQyxJQUFJO1lBQ3JCLE9BQU8sRUFBRSxDQUFDLGVBQWUsQ0FBQztRQUM1QixLQUFLLGFBQWEsQ0FBQyxRQUFRLENBQUM7UUFDNUIsS0FBSyxhQUFhLENBQUMsVUFBVSxDQUFDO1FBQzlCO1lBQ0UsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDO0tBQ3BCO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHtJbmplY3RGbGFnc30gZnJvbSAnLi4vY29yZSc7XG5pbXBvcnQgKiBhcyBvIGZyb20gJy4uL291dHB1dC9vdXRwdXRfYXN0JztcbmltcG9ydCB7SWRlbnRpZmllcnMgYXMgUjN9IGZyb20gJy4uL3JlbmRlcjMvcjNfaWRlbnRpZmllcnMnO1xuXG5pbXBvcnQge1IzQ29tcGlsZWRFeHByZXNzaW9uLCBSM1JlZmVyZW5jZSwgdHlwZVdpdGhQYXJhbWV0ZXJzfSBmcm9tICcuL3V0aWwnO1xuXG5cbi8qKlxuICogTWV0YWRhdGEgcmVxdWlyZWQgYnkgdGhlIGZhY3RvcnkgZ2VuZXJhdG9yIHRvIGdlbmVyYXRlIGEgYGZhY3RvcnlgIGZ1bmN0aW9uIGZvciBhIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUjNDb25zdHJ1Y3RvckZhY3RvcnlNZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBTdHJpbmcgbmFtZSBvZiB0aGUgdHlwZSBiZWluZyBnZW5lcmF0ZWQgKHVzZWQgdG8gbmFtZSB0aGUgZmFjdG9yeSBmdW5jdGlvbikuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBpbnRlcmZhY2UgdHlwZSBiZWluZyBjb25zdHJ1Y3RlZC5cbiAgICovXG4gIHR5cGU6IFIzUmVmZXJlbmNlO1xuXG4gIC8qKiBOdW1iZXIgb2YgYXJndW1lbnRzIGZvciB0aGUgYHR5cGVgLiAqL1xuICB0eXBlQXJndW1lbnRDb3VudDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBSZWdhcmRsZXNzIG9mIHdoZXRoZXIgYGZuT3JDbGFzc2AgaXMgYSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBvciBhIHVzZXItZGVmaW5lZCBmYWN0b3J5LCBpdFxuICAgKiBtYXkgaGF2ZSAwIG9yIG1vcmUgcGFyYW1ldGVycywgd2hpY2ggd2lsbCBiZSBpbmplY3RlZCBhY2NvcmRpbmcgdG8gdGhlIGBSM0RlcGVuZGVuY3lNZXRhZGF0YWBcbiAgICogZm9yIHRob3NlIHBhcmFtZXRlcnMuIElmIHRoaXMgaXMgYG51bGxgLCB0aGVuIHRoZSB0eXBlJ3MgY29uc3RydWN0b3IgaXMgbm9uZXhpc3RlbnQgYW5kIHdpbGxcbiAgICogYmUgaW5oZXJpdGVkIGZyb20gYGZuT3JDbGFzc2Agd2hpY2ggaXMgaW50ZXJwcmV0ZWQgYXMgdGhlIGN1cnJlbnQgdHlwZS4gSWYgdGhpcyBpcyBgJ2ludmFsaWQnYCxcbiAgICogdGhlbiBvbmUgb3IgbW9yZSBvZiB0aGUgcGFyYW1ldGVycyB3YXNuJ3QgcmVzb2x2YWJsZSBhbmQgYW55IGF0dGVtcHQgdG8gdXNlIHRoZXNlIGRlcHMgd2lsbFxuICAgKiByZXN1bHQgaW4gYSBydW50aW1lIGVycm9yLlxuICAgKi9cbiAgZGVwczogUjNEZXBlbmRlbmN5TWV0YWRhdGFbXXwnaW52YWxpZCd8bnVsbDtcblxuICAvKipcbiAgICogVHlwZSBvZiB0aGUgdGFyZ2V0IGJlaW5nIGNyZWF0ZWQgYnkgdGhlIGZhY3RvcnkuXG4gICAqL1xuICB0YXJnZXQ6IEZhY3RvcnlUYXJnZXQ7XG59XG5cbmV4cG9ydCBlbnVtIFIzRmFjdG9yeURlbGVnYXRlVHlwZSB7XG4gIENsYXNzID0gMCxcbiAgRnVuY3Rpb24gPSAxLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFIzRGVsZWdhdGVkRm5PckNsYXNzTWV0YWRhdGEgZXh0ZW5kcyBSM0NvbnN0cnVjdG9yRmFjdG9yeU1ldGFkYXRhIHtcbiAgZGVsZWdhdGU6IG8uRXhwcmVzc2lvbjtcbiAgZGVsZWdhdGVUeXBlOiBSM0ZhY3RvcnlEZWxlZ2F0ZVR5cGU7XG4gIGRlbGVnYXRlRGVwczogUjNEZXBlbmRlbmN5TWV0YWRhdGFbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSM0V4cHJlc3Npb25GYWN0b3J5TWV0YWRhdGEgZXh0ZW5kcyBSM0NvbnN0cnVjdG9yRmFjdG9yeU1ldGFkYXRhIHtcbiAgZXhwcmVzc2lvbjogby5FeHByZXNzaW9uO1xufVxuXG5leHBvcnQgdHlwZSBSM0ZhY3RvcnlNZXRhZGF0YSA9XG4gICAgUjNDb25zdHJ1Y3RvckZhY3RvcnlNZXRhZGF0YXxSM0RlbGVnYXRlZEZuT3JDbGFzc01ldGFkYXRhfFIzRXhwcmVzc2lvbkZhY3RvcnlNZXRhZGF0YTtcblxuZXhwb3J0IGVudW0gRmFjdG9yeVRhcmdldCB7XG4gIERpcmVjdGl2ZSA9IDAsXG4gIENvbXBvbmVudCA9IDEsXG4gIEluamVjdGFibGUgPSAyLFxuICBQaXBlID0gMyxcbiAgTmdNb2R1bGUgPSA0LFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFIzRGVwZW5kZW5jeU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSB0b2tlbiBvciB2YWx1ZSB0byBiZSBpbmplY3RlZC5cbiAgICogT3IgYG51bGxgIGlmIHRoZSBkZXBlbmRlbmN5IGNvdWxkIG5vdCBiZSByZXNvbHZlZCAtIG1ha2luZyBpdCBpbnZhbGlkLlxuICAgKi9cbiAgdG9rZW46IG8uRXhwcmVzc2lvbnxudWxsO1xuXG4gIC8qKlxuICAgKiBJZiBhbiBAQXR0cmlidXRlIGRlY29yYXRvciBpcyBwcmVzZW50LCB0aGlzIGlzIHRoZSBsaXRlcmFsIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBuYW1lLCBvclxuICAgKiB0aGUgdW5rbm93biB0eXBlIGlmIG5vIGxpdGVyYWwgdHlwZSBpcyBhdmFpbGFibGUgKGUuZy4gdGhlIGF0dHJpYnV0ZSBuYW1lIGlzIGFuIGV4cHJlc3Npb24pLlxuICAgKiBPdGhlcndpc2UgaXQgaXMgbnVsbDtcbiAgICovXG4gIGF0dHJpYnV0ZU5hbWVUeXBlOiBvLkV4cHJlc3Npb258bnVsbDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZGVwZW5kZW5jeSBoYXMgYW4gQEhvc3QgcXVhbGlmaWVyLlxuICAgKi9cbiAgaG9zdDogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZGVwZW5kZW5jeSBoYXMgYW4gQE9wdGlvbmFsIHF1YWxpZmllci5cbiAgICovXG4gIG9wdGlvbmFsOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBkZXBlbmRlbmN5IGhhcyBhbiBAU2VsZiBxdWFsaWZpZXIuXG4gICAqL1xuICBzZWxmOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBkZXBlbmRlbmN5IGhhcyBhbiBAU2tpcFNlbGYgcXVhbGlmaWVyLlxuICAgKi9cbiAgc2tpcFNlbGY6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgZmFjdG9yeSBmdW5jdGlvbiBleHByZXNzaW9uIGZvciB0aGUgZ2l2ZW4gYFIzRmFjdG9yeU1ldGFkYXRhYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVGYWN0b3J5RnVuY3Rpb24obWV0YTogUjNGYWN0b3J5TWV0YWRhdGEpOiBSM0NvbXBpbGVkRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHQgPSBvLnZhcmlhYmxlKCd0Jyk7XG4gIGxldCBiYXNlRmFjdG9yeVZhcjogby5SZWFkVmFyRXhwcnxudWxsID0gbnVsbDtcblxuICAvLyBUaGUgdHlwZSB0byBpbnN0YW50aWF0ZSB2aWEgY29uc3RydWN0b3IgaW52b2NhdGlvbi4gSWYgdGhlcmUgaXMgbm8gZGVsZWdhdGVkIGZhY3RvcnksIG1lYW5pbmdcbiAgLy8gdGhpcyB0eXBlIGlzIGFsd2F5cyBjcmVhdGVkIGJ5IGNvbnN0cnVjdG9yIGludm9jYXRpb24sIHRoZW4gdGhpcyBpcyB0aGUgdHlwZS10by1jcmVhdGVcbiAgLy8gcGFyYW1ldGVyIHByb3ZpZGVkIGJ5IHRoZSB1c2VyICh0KSBpZiBzcGVjaWZpZWQsIG9yIHRoZSBjdXJyZW50IHR5cGUgaWYgbm90LiBJZiB0aGVyZSBpcyBhXG4gIC8vIGRlbGVnYXRlZCBmYWN0b3J5ICh3aGljaCBpcyB1c2VkIHRvIGNyZWF0ZSB0aGUgY3VycmVudCB0eXBlKSB0aGVuIHRoaXMgaXMgb25seSB0aGUgdHlwZS10by1cbiAgLy8gY3JlYXRlIHBhcmFtZXRlciAodCkuXG4gIGNvbnN0IHR5cGVGb3JDdG9yID0gIWlzRGVsZWdhdGVkRmFjdG9yeU1ldGFkYXRhKG1ldGEpID9cbiAgICAgIG5ldyBvLkJpbmFyeU9wZXJhdG9yRXhwcihvLkJpbmFyeU9wZXJhdG9yLk9yLCB0LCBtZXRhLnR5cGUudmFsdWUpIDpcbiAgICAgIHQ7XG5cbiAgbGV0IGN0b3JFeHByOiBvLkV4cHJlc3Npb258bnVsbCA9IG51bGw7XG4gIGlmIChtZXRhLmRlcHMgIT09IG51bGwpIHtcbiAgICAvLyBUaGVyZSBpcyBhIGNvbnN0cnVjdG9yIChlaXRoZXIgZXhwbGljaXRseSBvciBpbXBsaWNpdGx5IGRlZmluZWQpLlxuICAgIGlmIChtZXRhLmRlcHMgIT09ICdpbnZhbGlkJykge1xuICAgICAgY3RvckV4cHIgPSBuZXcgby5JbnN0YW50aWF0ZUV4cHIodHlwZUZvckN0b3IsIGluamVjdERlcGVuZGVuY2llcyhtZXRhLmRlcHMsIG1ldGEudGFyZ2V0KSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoZXJlIGlzIG5vIGNvbnN0cnVjdG9yLCB1c2UgdGhlIGJhc2UgY2xhc3MnIGZhY3RvcnkgdG8gY29uc3RydWN0IHR5cGVGb3JDdG9yLlxuICAgIGJhc2VGYWN0b3J5VmFyID0gby52YXJpYWJsZShgybUke21ldGEubmFtZX1fQmFzZUZhY3RvcnlgKTtcbiAgICBjdG9yRXhwciA9IGJhc2VGYWN0b3J5VmFyLmNhbGxGbihbdHlwZUZvckN0b3JdKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHk6IG8uU3RhdGVtZW50W10gPSBbXTtcbiAgbGV0IHJldEV4cHI6IG8uRXhwcmVzc2lvbnxudWxsID0gbnVsbDtcblxuICBmdW5jdGlvbiBtYWtlQ29uZGl0aW9uYWxGYWN0b3J5KG5vbkN0b3JFeHByOiBvLkV4cHJlc3Npb24pOiBvLlJlYWRWYXJFeHByIHtcbiAgICBjb25zdCByID0gby52YXJpYWJsZSgncicpO1xuICAgIGJvZHkucHVzaChyLnNldChvLk5VTExfRVhQUikudG9EZWNsU3RtdCgpKTtcbiAgICBjb25zdCBjdG9yU3RtdCA9IGN0b3JFeHByICE9PSBudWxsID8gci5zZXQoY3RvckV4cHIpLnRvU3RtdCgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgby5pbXBvcnRFeHByKFIzLmludmFsaWRGYWN0b3J5KS5jYWxsRm4oW10pLnRvU3RtdCgpO1xuICAgIGJvZHkucHVzaChvLmlmU3RtdCh0LCBbY3RvclN0bXRdLCBbci5zZXQobm9uQ3RvckV4cHIpLnRvU3RtdCgpXSkpO1xuICAgIHJldHVybiByO1xuICB9XG5cbiAgaWYgKGlzRGVsZWdhdGVkRmFjdG9yeU1ldGFkYXRhKG1ldGEpKSB7XG4gICAgLy8gVGhpcyB0eXBlIGlzIGNyZWF0ZWQgd2l0aCBhIGRlbGVnYXRlZCBmYWN0b3J5LiBJZiBhIHR5cGUgcGFyYW1ldGVyIGlzIG5vdCBzcGVjaWZpZWQsIGNhbGxcbiAgICAvLyB0aGUgZmFjdG9yeSBpbnN0ZWFkLlxuICAgIGNvbnN0IGRlbGVnYXRlQXJncyA9IGluamVjdERlcGVuZGVuY2llcyhtZXRhLmRlbGVnYXRlRGVwcywgbWV0YS50YXJnZXQpO1xuICAgIC8vIEVpdGhlciBjYWxsIGBuZXcgZGVsZWdhdGUoLi4uKWAgb3IgYGRlbGVnYXRlKC4uLilgIGRlcGVuZGluZyBvbiBtZXRhLmRlbGVnYXRlVHlwZS5cbiAgICBjb25zdCBmYWN0b3J5RXhwciA9IG5ldyAoXG4gICAgICAgIG1ldGEuZGVsZWdhdGVUeXBlID09PSBSM0ZhY3RvcnlEZWxlZ2F0ZVR5cGUuQ2xhc3MgP1xuICAgICAgICAgICAgby5JbnN0YW50aWF0ZUV4cHIgOlxuICAgICAgICAgICAgby5JbnZva2VGdW5jdGlvbkV4cHIpKG1ldGEuZGVsZWdhdGUsIGRlbGVnYXRlQXJncyk7XG4gICAgcmV0RXhwciA9IG1ha2VDb25kaXRpb25hbEZhY3RvcnkoZmFjdG9yeUV4cHIpO1xuICB9IGVsc2UgaWYgKGlzRXhwcmVzc2lvbkZhY3RvcnlNZXRhZGF0YShtZXRhKSkge1xuICAgIC8vIFRPRE8oYWx4aHViKTogZGVjaWRlIHdoZXRoZXIgdG8gbG93ZXIgdGhlIHZhbHVlIGhlcmUgb3IgaW4gdGhlIGNhbGxlclxuICAgIHJldEV4cHIgPSBtYWtlQ29uZGl0aW9uYWxGYWN0b3J5KG1ldGEuZXhwcmVzc2lvbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0RXhwciA9IGN0b3JFeHByO1xuICB9XG5cblxuICBpZiAocmV0RXhwciA9PT0gbnVsbCkge1xuICAgIC8vIFRoZSBleHByZXNzaW9uIGNhbm5vdCBiZSBmb3JtZWQgc28gcmVuZGVyIGFuIGDJtcm1aW52YWxpZEZhY3RvcnkoKWAgY2FsbC5cbiAgICBib2R5LnB1c2goby5pbXBvcnRFeHByKFIzLmludmFsaWRGYWN0b3J5KS5jYWxsRm4oW10pLnRvU3RtdCgpKTtcbiAgfSBlbHNlIGlmIChiYXNlRmFjdG9yeVZhciAhPT0gbnVsbCkge1xuICAgIC8vIFRoaXMgZmFjdG9yeSB1c2VzIGEgYmFzZSBmYWN0b3J5LCBzbyBjYWxsIGDJtcm1Z2V0SW5oZXJpdGVkRmFjdG9yeSgpYCB0byBjb21wdXRlIGl0LlxuICAgIGNvbnN0IGdldEluaGVyaXRlZEZhY3RvcnlDYWxsID0gby5pbXBvcnRFeHByKFIzLmdldEluaGVyaXRlZEZhY3RvcnkpLmNhbGxGbihbbWV0YS50eXBlLnZhbHVlXSk7XG4gICAgLy8gTWVtb2l6ZSB0aGUgYmFzZSBmYWN0b3J5Rm46IGBiYXNlRmFjdG9yeSB8fCAoYmFzZUZhY3RvcnkgPSDJtcm1Z2V0SW5oZXJpdGVkRmFjdG9yeSguLi4pKWBcbiAgICBjb25zdCBiYXNlRmFjdG9yeSA9IG5ldyBvLkJpbmFyeU9wZXJhdG9yRXhwcihcbiAgICAgICAgby5CaW5hcnlPcGVyYXRvci5PciwgYmFzZUZhY3RvcnlWYXIsIGJhc2VGYWN0b3J5VmFyLnNldChnZXRJbmhlcml0ZWRGYWN0b3J5Q2FsbCkpO1xuICAgIGJvZHkucHVzaChuZXcgby5SZXR1cm5TdGF0ZW1lbnQoYmFzZUZhY3RvcnkuY2FsbEZuKFt0eXBlRm9yQ3Rvcl0pKSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBzdHJhaWdodGZvcndhcmQgZmFjdG9yeSwganVzdCByZXR1cm4gaXQuXG4gICAgYm9keS5wdXNoKG5ldyBvLlJldHVyblN0YXRlbWVudChyZXRFeHByKSk7XG4gIH1cblxuICBsZXQgZmFjdG9yeUZuOiBvLkV4cHJlc3Npb24gPSBvLmZuKFxuICAgICAgW25ldyBvLkZuUGFyYW0oJ3QnLCBvLkRZTkFNSUNfVFlQRSldLCBib2R5LCBvLklORkVSUkVEX1RZUEUsIHVuZGVmaW5lZCxcbiAgICAgIGAke21ldGEubmFtZX1fRmFjdG9yeWApO1xuXG4gIGlmIChiYXNlRmFjdG9yeVZhciAhPT0gbnVsbCkge1xuICAgIC8vIFRoZXJlIGlzIGEgYmFzZSBmYWN0b3J5IHZhcmlhYmxlIHNvIHdyYXAgaXRzIGRlY2xhcmF0aW9uIGFsb25nIHdpdGggdGhlIGZhY3RvcnkgZnVuY3Rpb24gaW50b1xuICAgIC8vIGFuIElJRkUuXG4gICAgZmFjdG9yeUZuID0gby5mbihbXSwgW1xuICAgICAgICAgICAgICAgICAgIG5ldyBvLkRlY2xhcmVWYXJTdG10KGJhc2VGYWN0b3J5VmFyLm5hbWUhKSwgbmV3IG8uUmV0dXJuU3RhdGVtZW50KGZhY3RvcnlGbilcbiAgICAgICAgICAgICAgICAgXSkuY2FsbEZuKFtdLCAvKiBzb3VyY2VTcGFuICovIHVuZGVmaW5lZCwgLyogcHVyZSAqLyB0cnVlKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZXhwcmVzc2lvbjogZmFjdG9yeUZuLFxuICAgIHN0YXRlbWVudHM6IFtdLFxuICAgIHR5cGU6IGNyZWF0ZUZhY3RvcnlUeXBlKG1ldGEpLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmFjdG9yeVR5cGUobWV0YTogUjNGYWN0b3J5TWV0YWRhdGEpIHtcbiAgY29uc3QgY3RvckRlcHNUeXBlID1cbiAgICAgIG1ldGEuZGVwcyAhPT0gbnVsbCAmJiBtZXRhLmRlcHMgIT09ICdpbnZhbGlkJyA/IGNyZWF0ZUN0b3JEZXBzVHlwZShtZXRhLmRlcHMpIDogby5OT05FX1RZUEU7XG4gIHJldHVybiBvLmV4cHJlc3Npb25UeXBlKG8uaW1wb3J0RXhwcihcbiAgICAgIFIzLkZhY3RvcnlEZWNsYXJhdGlvbixcbiAgICAgIFt0eXBlV2l0aFBhcmFtZXRlcnMobWV0YS50eXBlLnR5cGUsIG1ldGEudHlwZUFyZ3VtZW50Q291bnQpLCBjdG9yRGVwc1R5cGVdKSk7XG59XG5cbmZ1bmN0aW9uIGluamVjdERlcGVuZGVuY2llcyhkZXBzOiBSM0RlcGVuZGVuY3lNZXRhZGF0YVtdLCB0YXJnZXQ6IEZhY3RvcnlUYXJnZXQpOiBvLkV4cHJlc3Npb25bXSB7XG4gIHJldHVybiBkZXBzLm1hcCgoZGVwLCBpbmRleCkgPT4gY29tcGlsZUluamVjdERlcGVuZGVuY3koZGVwLCB0YXJnZXQsIGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVJbmplY3REZXBlbmRlbmN5KFxuICAgIGRlcDogUjNEZXBlbmRlbmN5TWV0YWRhdGEsIHRhcmdldDogRmFjdG9yeVRhcmdldCwgaW5kZXg6IG51bWJlcik6IG8uRXhwcmVzc2lvbiB7XG4gIC8vIEludGVycHJldCB0aGUgZGVwZW5kZW5jeSBhY2NvcmRpbmcgdG8gaXRzIHJlc29sdmVkIHR5cGUuXG4gIGlmIChkZXAudG9rZW4gPT09IG51bGwpIHtcbiAgICByZXR1cm4gby5pbXBvcnRFeHByKFIzLmludmFsaWRGYWN0b3J5RGVwKS5jYWxsRm4oW28ubGl0ZXJhbChpbmRleCldKTtcbiAgfSBlbHNlIGlmIChkZXAuYXR0cmlidXRlTmFtZVR5cGUgPT09IG51bGwpIHtcbiAgICAvLyBCdWlsZCB1cCB0aGUgaW5qZWN0aW9uIGZsYWdzIGFjY29yZGluZyB0byB0aGUgbWV0YWRhdGEuXG4gICAgY29uc3QgZmxhZ3MgPSBJbmplY3RGbGFncy5EZWZhdWx0IHwgKGRlcC5zZWxmID8gSW5qZWN0RmxhZ3MuU2VsZiA6IDApIHxcbiAgICAgICAgKGRlcC5za2lwU2VsZiA/IEluamVjdEZsYWdzLlNraXBTZWxmIDogMCkgfCAoZGVwLmhvc3QgPyBJbmplY3RGbGFncy5Ib3N0IDogMCkgfFxuICAgICAgICAoZGVwLm9wdGlvbmFsID8gSW5qZWN0RmxhZ3MuT3B0aW9uYWwgOiAwKSB8XG4gICAgICAgICh0YXJnZXQgPT09IEZhY3RvcnlUYXJnZXQuUGlwZSA/IEluamVjdEZsYWdzLkZvclBpcGUgOiAwKTtcblxuICAgIC8vIElmIHRoaXMgZGVwZW5kZW5jeSBpcyBvcHRpb25hbCBvciBvdGhlcndpc2UgaGFzIG5vbi1kZWZhdWx0IGZsYWdzLCB0aGVuIGFkZGl0aW9uYWxcbiAgICAvLyBwYXJhbWV0ZXJzIGRlc2NyaWJpbmcgaG93IHRvIGluamVjdCB0aGUgZGVwZW5kZW5jeSBtdXN0IGJlIHBhc3NlZCB0byB0aGUgaW5qZWN0IGZ1bmN0aW9uXG4gICAgLy8gdGhhdCdzIGJlaW5nIHVzZWQuXG4gICAgbGV0IGZsYWdzUGFyYW06IG8uTGl0ZXJhbEV4cHJ8bnVsbCA9XG4gICAgICAgIChmbGFncyAhPT0gSW5qZWN0RmxhZ3MuRGVmYXVsdCB8fCBkZXAub3B0aW9uYWwpID8gby5saXRlcmFsKGZsYWdzKSA6IG51bGw7XG5cbiAgICAvLyBCdWlsZCB1cCB0aGUgYXJndW1lbnRzIHRvIHRoZSBpbmplY3RGbiBjYWxsLlxuICAgIGNvbnN0IGluamVjdEFyZ3MgPSBbZGVwLnRva2VuXTtcbiAgICBpZiAoZmxhZ3NQYXJhbSkge1xuICAgICAgaW5qZWN0QXJncy5wdXNoKGZsYWdzUGFyYW0pO1xuICAgIH1cbiAgICBjb25zdCBpbmplY3RGbiA9IGdldEluamVjdEZuKHRhcmdldCk7XG4gICAgcmV0dXJuIG8uaW1wb3J0RXhwcihpbmplY3RGbikuY2FsbEZuKGluamVjdEFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoZSBgZGVwLmF0dHJpYnV0ZVR5cGVOYW1lYCB2YWx1ZSBpcyBkZWZpbmVkLCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB0aGlzIGlzIGFuIGBAQXR0cmlidXRlKClgXG4gICAgLy8gdHlwZSBkZXBlbmRlbmN5LiBGb3IgdGhlIGdlbmVyYXRlZCBKUyB3ZSBzdGlsbCB3YW50IHRvIHVzZSB0aGUgYGRlcC50b2tlbmAgdmFsdWUgaW4gY2FzZSB0aGVcbiAgICAvLyBuYW1lIGdpdmVuIGZvciB0aGUgYXR0cmlidXRlIGlzIG5vdCBhIHN0cmluZyBsaXRlcmFsLiBGb3IgZXhhbXBsZSBnaXZlbiBgQEF0dHJpYnV0ZShmb28oKSlgLFxuICAgIC8vIHdlIHdhbnQgdG8gZ2VuZXJhdGUgYMm1ybVpbmplY3RBdHRyaWJ1dGUoZm9vKCkpYC5cbiAgICAvL1xuICAgIC8vIFRoZSBgZGVwLmF0dHJpYnV0ZVR5cGVOYW1lYCBpcyBvbmx5IGFjdHVhbGx5IHVzZWQgKGluIGBjcmVhdGVDdG9yRGVwVHlwZSgpYCkgdG8gZ2VuZXJhdGVcbiAgICAvLyB0eXBpbmdzLlxuICAgIHJldHVybiBvLmltcG9ydEV4cHIoUjMuaW5qZWN0QXR0cmlidXRlKS5jYWxsRm4oW2RlcC50b2tlbl0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUN0b3JEZXBzVHlwZShkZXBzOiBSM0RlcGVuZGVuY3lNZXRhZGF0YVtdKTogby5UeXBlIHtcbiAgbGV0IGhhc1R5cGVzID0gZmFsc2U7XG4gIGNvbnN0IGF0dHJpYnV0ZVR5cGVzID0gZGVwcy5tYXAoZGVwID0+IHtcbiAgICBjb25zdCB0eXBlID0gY3JlYXRlQ3RvckRlcFR5cGUoZGVwKTtcbiAgICBpZiAodHlwZSAhPT0gbnVsbCkge1xuICAgICAgaGFzVHlwZXMgPSB0cnVlO1xuICAgICAgcmV0dXJuIHR5cGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBvLmxpdGVyYWwobnVsbCk7XG4gICAgfVxuICB9KTtcblxuICBpZiAoaGFzVHlwZXMpIHtcbiAgICByZXR1cm4gby5leHByZXNzaW9uVHlwZShvLmxpdGVyYWxBcnIoYXR0cmlidXRlVHlwZXMpKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gby5OT05FX1RZUEU7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ3RvckRlcFR5cGUoZGVwOiBSM0RlcGVuZGVuY3lNZXRhZGF0YSk6IG8uTGl0ZXJhbE1hcEV4cHJ8bnVsbCB7XG4gIGNvbnN0IGVudHJpZXM6IHtrZXk6IHN0cmluZywgcXVvdGVkOiBib29sZWFuLCB2YWx1ZTogby5FeHByZXNzaW9ufVtdID0gW107XG5cbiAgaWYgKGRlcC5hdHRyaWJ1dGVOYW1lVHlwZSAhPT0gbnVsbCkge1xuICAgIGVudHJpZXMucHVzaCh7a2V5OiAnYXR0cmlidXRlJywgdmFsdWU6IGRlcC5hdHRyaWJ1dGVOYW1lVHlwZSwgcXVvdGVkOiBmYWxzZX0pO1xuICB9XG4gIGlmIChkZXAub3B0aW9uYWwpIHtcbiAgICBlbnRyaWVzLnB1c2goe2tleTogJ29wdGlvbmFsJywgdmFsdWU6IG8ubGl0ZXJhbCh0cnVlKSwgcXVvdGVkOiBmYWxzZX0pO1xuICB9XG4gIGlmIChkZXAuaG9zdCkge1xuICAgIGVudHJpZXMucHVzaCh7a2V5OiAnaG9zdCcsIHZhbHVlOiBvLmxpdGVyYWwodHJ1ZSksIHF1b3RlZDogZmFsc2V9KTtcbiAgfVxuICBpZiAoZGVwLnNlbGYpIHtcbiAgICBlbnRyaWVzLnB1c2goe2tleTogJ3NlbGYnLCB2YWx1ZTogby5saXRlcmFsKHRydWUpLCBxdW90ZWQ6IGZhbHNlfSk7XG4gIH1cbiAgaWYgKGRlcC5za2lwU2VsZikge1xuICAgIGVudHJpZXMucHVzaCh7a2V5OiAnc2tpcFNlbGYnLCB2YWx1ZTogby5saXRlcmFsKHRydWUpLCBxdW90ZWQ6IGZhbHNlfSk7XG4gIH1cblxuICByZXR1cm4gZW50cmllcy5sZW5ndGggPiAwID8gby5saXRlcmFsTWFwKGVudHJpZXMpIDogbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGVsZWdhdGVkRmFjdG9yeU1ldGFkYXRhKG1ldGE6IFIzRmFjdG9yeU1ldGFkYXRhKTpcbiAgICBtZXRhIGlzIFIzRGVsZWdhdGVkRm5PckNsYXNzTWV0YWRhdGEge1xuICByZXR1cm4gKG1ldGEgYXMgYW55KS5kZWxlZ2F0ZVR5cGUgIT09IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRXhwcmVzc2lvbkZhY3RvcnlNZXRhZGF0YShtZXRhOiBSM0ZhY3RvcnlNZXRhZGF0YSk6XG4gICAgbWV0YSBpcyBSM0V4cHJlc3Npb25GYWN0b3J5TWV0YWRhdGEge1xuICByZXR1cm4gKG1ldGEgYXMgYW55KS5leHByZXNzaW9uICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGdldEluamVjdEZuKHRhcmdldDogRmFjdG9yeVRhcmdldCk6IG8uRXh0ZXJuYWxSZWZlcmVuY2Uge1xuICBzd2l0Y2ggKHRhcmdldCkge1xuICAgIGNhc2UgRmFjdG9yeVRhcmdldC5Db21wb25lbnQ6XG4gICAgY2FzZSBGYWN0b3J5VGFyZ2V0LkRpcmVjdGl2ZTpcbiAgICBjYXNlIEZhY3RvcnlUYXJnZXQuUGlwZTpcbiAgICAgIHJldHVybiBSMy5kaXJlY3RpdmVJbmplY3Q7XG4gICAgY2FzZSBGYWN0b3J5VGFyZ2V0Lk5nTW9kdWxlOlxuICAgIGNhc2UgRmFjdG9yeVRhcmdldC5JbmplY3RhYmxlOlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gUjMuaW5qZWN0O1xuICB9XG59XG4iXX0=