UNPKG

@angular/core

Version:

Angular - the core framework

460 lines 70 kB
/** * @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 { __read, __spread } from "tslib"; import { getCompilerFacade } from '../../compiler/compiler_facade'; import { resolveForwardRef } from '../../di/forward_ref'; import { NG_INJ_DEF } from '../../di/interface/defs'; import { reflectDependencies } from '../../di/jit/util'; import { deepForEach, flatten } from '../../util/array_utils'; import { assertDefined } from '../../util/assert'; import { getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef } from '../definition'; import { NG_COMP_DEF, NG_DIR_DEF, NG_MOD_DEF, NG_PIPE_DEF } from '../fields'; import { maybeUnwrapFn, stringifyForError } from '../util/misc_utils'; import { angularCoreEnv } from './environment'; var EMPTY_ARRAY = []; var moduleQueue = []; /** * Enqueues moduleDef to be checked later to see if scope can be set on its * component declarations. */ function enqueueModuleForDelayedScoping(moduleType, ngModule) { moduleQueue.push({ moduleType: moduleType, ngModule: ngModule }); } var flushingModuleQueue = false; /** * Loops over queued module definitions, if a given module definition has all of its * declarations resolved, it dequeues that module definition and sets the scope on * its declarations. */ export function flushModuleScopingQueueAsMuchAsPossible() { if (!flushingModuleQueue) { flushingModuleQueue = true; try { for (var i = moduleQueue.length - 1; i >= 0; i--) { var _a = moduleQueue[i], moduleType = _a.moduleType, ngModule = _a.ngModule; if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) { // dequeue moduleQueue.splice(i, 1); setScopeOnDeclaredComponents(moduleType, ngModule); } } } finally { flushingModuleQueue = false; } } } /** * Returns truthy if a declaration has resolved. If the declaration happens to be * an array of declarations, it will recurse to check each declaration in that array * (which may also be arrays). */ function isResolvedDeclaration(declaration) { if (Array.isArray(declaration)) { return declaration.every(isResolvedDeclaration); } return !!resolveForwardRef(declaration); } /** * Compiles a module in JIT mode. * * This function automatically gets called when a class has a `@NgModule` decorator. */ export function compileNgModule(moduleType, ngModule) { if (ngModule === void 0) { ngModule = {}; } compileNgModuleDefs(moduleType, ngModule); // Because we don't know if all declarations have resolved yet at the moment the // NgModule decorator is executing, we're enqueueing the setting of module scope // on its declarations to be run at a later time when all declarations for the module, // including forward refs, have resolved. enqueueModuleForDelayedScoping(moduleType, ngModule); } /** * Compiles and adds the `ɵmod` and `ɵinj` properties to the module class. * * It's possible to compile a module via this API which will allow duplicate declarations in its * root. */ export function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot) { if (allowDuplicateDeclarationsInRoot === void 0) { allowDuplicateDeclarationsInRoot = false; } ngDevMode && assertDefined(moduleType, 'Required value moduleType'); ngDevMode && assertDefined(ngModule, 'Required value ngModule'); var declarations = flatten(ngModule.declarations || EMPTY_ARRAY); var ngModuleDef = null; Object.defineProperty(moduleType, NG_MOD_DEF, { configurable: true, get: function () { if (ngModuleDef === null) { if (ngDevMode && ngModule.imports && ngModule.imports.indexOf(moduleType) > -1) { // We need to assert this immediately, because allowing it to continue will cause it to // go into an infinite loop before we've reached the point where we throw all the errors. throw new Error("'" + stringifyForError(moduleType) + "' module can't import itself"); } ngModuleDef = getCompilerFacade().compileNgModule(angularCoreEnv, "ng:///" + moduleType.name + "/\u0275mod.js", { type: moduleType, bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY).map(resolveForwardRef), declarations: declarations.map(resolveForwardRef), imports: flatten(ngModule.imports || EMPTY_ARRAY) .map(resolveForwardRef) .map(expandModuleWithProviders), exports: flatten(ngModule.exports || EMPTY_ARRAY) .map(resolveForwardRef) .map(expandModuleWithProviders), schemas: ngModule.schemas ? flatten(ngModule.schemas) : null, id: ngModule.id || null, }); // Set `schemas` on ngModuleDef to an empty array in JIT mode to indicate that runtime // should verify that there are no unknown elements in a template. In AOT mode, that check // happens at compile time and `schemas` information is not present on Component and Module // defs after compilation (so the check doesn't happen the second time at runtime). if (!ngModuleDef.schemas) { ngModuleDef.schemas = []; } } return ngModuleDef; } }); var ngInjectorDef = null; Object.defineProperty(moduleType, NG_INJ_DEF, { get: function () { if (ngInjectorDef === null) { ngDevMode && verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot); var meta = { name: moduleType.name, type: moduleType, deps: reflectDependencies(moduleType), providers: ngModule.providers || EMPTY_ARRAY, imports: [ (ngModule.imports || EMPTY_ARRAY).map(resolveForwardRef), (ngModule.exports || EMPTY_ARRAY).map(resolveForwardRef), ], }; ngInjectorDef = getCompilerFacade().compileInjector(angularCoreEnv, "ng:///" + moduleType.name + "/\u0275inj.js", meta); } return ngInjectorDef; }, // Make the property configurable in dev mode to allow overriding in tests configurable: !!ngDevMode, }); } function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) { if (verifiedNgModule.get(moduleType)) return; verifiedNgModule.set(moduleType, true); moduleType = resolveForwardRef(moduleType); var ngModuleDef; if (importingModule) { ngModuleDef = getNgModuleDef(moduleType); if (!ngModuleDef) { throw new Error("Unexpected value '" + moduleType.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation."); } } else { ngModuleDef = getNgModuleDef(moduleType, true); } var errors = []; var declarations = maybeUnwrapFn(ngModuleDef.declarations); var imports = maybeUnwrapFn(ngModuleDef.imports); flatten(imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) { verifySemanticsOfNgModuleImport(mod, moduleType); verifySemanticsOfNgModuleDef(mod, false, moduleType); }); var exports = maybeUnwrapFn(ngModuleDef.exports); declarations.forEach(verifyDeclarationsHaveDefinitions); declarations.forEach(verifyDirectivesHaveSelector); var combinedDeclarations = __spread(declarations.map(resolveForwardRef), flatten(imports.map(computeCombinedExports)).map(resolveForwardRef)); exports.forEach(verifyExportsAreDeclaredOrReExported); declarations.forEach(function (decl) { return verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot); }); declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule); var ngModule = getAnnotation(moduleType, 'NgModule'); if (ngModule) { ngModule.imports && flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) { verifySemanticsOfNgModuleImport(mod, moduleType); verifySemanticsOfNgModuleDef(mod, false, moduleType); }); ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType); ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule); ngModule.entryComponents && deepForEach(ngModule.entryComponents, verifyComponentIsPartOfNgModule); } // Throw Error if any errors were detected. if (errors.length) { throw new Error(errors.join('\n')); } //////////////////////////////////////////////////////////////////////////////////////////////// function verifyDeclarationsHaveDefinitions(type) { type = resolveForwardRef(type); var def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type); if (!def) { errors.push("Unexpected value '" + stringifyForError(type) + "' declared by the module '" + stringifyForError(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation."); } } function verifyDirectivesHaveSelector(type) { type = resolveForwardRef(type); var def = getDirectiveDef(type); if (!getComponentDef(type) && def && def.selectors.length == 0) { errors.push("Directive " + stringifyForError(type) + " has no selector, please add it!"); } } function verifyExportsAreDeclaredOrReExported(type) { type = resolveForwardRef(type); var kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' || getPipeDef(type) && 'pipe'; if (kind) { // only checked if we are declared as Component, Directive, or Pipe // Modules don't need to be declared or imported. if (combinedDeclarations.lastIndexOf(type) === -1) { // We are exporting something which we don't explicitly declare or import. errors.push("Can't export " + kind + " " + stringifyForError(type) + " from " + stringifyForError(moduleType) + " as it was neither declared nor imported!"); } } } function verifyDeclarationIsUnique(type, suppressErrors) { type = resolveForwardRef(type); var existingModule = ownerNgModule.get(type); if (existingModule && existingModule !== moduleType) { if (!suppressErrors) { var modules = [existingModule, moduleType].map(stringifyForError).sort(); errors.push("Type " + stringifyForError(type) + " is part of the declarations of 2 modules: " + modules[0] + " and " + modules[1] + "! " + ("Please consider moving " + stringifyForError(type) + " to a higher module that imports " + modules[0] + " and " + modules[1] + ". ") + ("You can also create a new NgModule that exports and includes " + stringifyForError(type) + " then import that NgModule in " + modules[0] + " and " + modules[1] + ".")); } } else { // Mark type as having owner. ownerNgModule.set(type, moduleType); } } function verifyComponentIsPartOfNgModule(type) { type = resolveForwardRef(type); var existingModule = ownerNgModule.get(type); if (!existingModule) { errors.push("Component " + stringifyForError(type) + " is not part of any NgModule or the module has not been imported into your module."); } } function verifyCorrectBootstrapType(type) { type = resolveForwardRef(type); if (!getComponentDef(type)) { errors.push(stringifyForError(type) + " cannot be used as an entry component."); } } function verifyComponentEntryComponentsIsPartOfNgModule(type) { type = resolveForwardRef(type); if (getComponentDef(type)) { // We know we are component var component = getAnnotation(type, 'Component'); if (component && component.entryComponents) { deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule); } } } function verifySemanticsOfNgModuleImport(type, importingModule) { type = resolveForwardRef(type); if (getComponentDef(type) || getDirectiveDef(type)) { throw new Error("Unexpected directive '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation."); } if (getPipeDef(type)) { throw new Error("Unexpected pipe '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation."); } } } function unwrapModuleWithProvidersImports(typeOrWithProviders) { typeOrWithProviders = resolveForwardRef(typeOrWithProviders); return typeOrWithProviders.ngModule || typeOrWithProviders; } function getAnnotation(type, name) { var annotation = null; collect(type.__annotations__); collect(type.decorators); return annotation; function collect(annotations) { if (annotations) { annotations.forEach(readAnnotation); } } function readAnnotation(decorator) { if (!annotation) { var proto = Object.getPrototypeOf(decorator); if (proto.ngMetadataName == name) { annotation = decorator; } else if (decorator.type) { var proto_1 = Object.getPrototypeOf(decorator.type); if (proto_1.ngMetadataName == name) { annotation = decorator.args[0]; } } } } } /** * Keep track of compiled components. This is needed because in tests we often want to compile the * same component with more than one NgModule. This would cause an error unless we reset which * NgModule the component belongs to. We keep the list of compiled components here so that the * TestBed can reset it later. */ var ownerNgModule = new Map(); var verifiedNgModule = new Map(); export function resetCompiledComponents() { ownerNgModule = new Map(); verifiedNgModule = new Map(); moduleQueue.length = 0; } /** * Computes the combined declarations of explicit declarations, as well as declarations inherited by * traversing the exports of imported modules. * @param type */ function computeCombinedExports(type) { type = resolveForwardRef(type); var ngModuleDef = getNgModuleDef(type, true); return __spread(flatten(maybeUnwrapFn(ngModuleDef.exports).map(function (type) { var ngModuleDef = getNgModuleDef(type); if (ngModuleDef) { verifySemanticsOfNgModuleDef(type, false); return computeCombinedExports(type); } else { return type; } }))); } /** * Some declared components may be compiled asynchronously, and thus may not have their * ɵcmp set yet. If this is the case, then a reference to the module is written into * the `ngSelectorScope` property of the declared type. */ function setScopeOnDeclaredComponents(moduleType, ngModule) { var declarations = flatten(ngModule.declarations || EMPTY_ARRAY); var transitiveScopes = transitiveScopesFor(moduleType); declarations.forEach(function (declaration) { if (declaration.hasOwnProperty(NG_COMP_DEF)) { // A `ɵcmp` field exists - go ahead and patch the component directly. var component = declaration; var componentDef = getComponentDef(component); patchComponentDefWithScope(componentDef, transitiveScopes); } else if (!declaration.hasOwnProperty(NG_DIR_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) { // Set `ngSelectorScope` for future reference when the component compilation finishes. declaration.ngSelectorScope = moduleType; } }); } /** * Patch the definition of a component with directives and pipes from the compilation scope of * a given module. */ export function patchComponentDefWithScope(componentDef, transitiveScopes) { componentDef.directiveDefs = function () { return Array.from(transitiveScopes.compilation.directives) .map(function (dir) { return dir.hasOwnProperty(NG_COMP_DEF) ? getComponentDef(dir) : getDirectiveDef(dir); }) .filter(function (def) { return !!def; }); }; componentDef.pipeDefs = function () { return Array.from(transitiveScopes.compilation.pipes).map(function (pipe) { return getPipeDef(pipe); }); }; componentDef.schemas = transitiveScopes.schemas; // Since we avoid Components/Directives/Pipes recompiling in case there are no overrides, we // may face a problem where previously compiled defs available to a given Component/Directive // are cached in TView and may become stale (in case any of these defs gets recompiled). In // order to avoid this problem, we force fresh TView to be created. componentDef.tView = null; } /** * Compute the pair of transitive scopes (compilation scope and exported scope) for a given module. * * This operation is memoized and the result is cached on the module's definition. This function can * be called on modules with components that have not fully compiled yet, but the result should not * be used until they have. * * @param moduleType module that transitive scope should be calculated for. */ export function transitiveScopesFor(moduleType) { if (!isNgModule(moduleType)) { throw new Error(moduleType.name + " does not have a module def (\u0275mod property)"); } var def = getNgModuleDef(moduleType); if (def.transitiveCompileScopes !== null) { return def.transitiveCompileScopes; } var scopes = { schemas: def.schemas || null, compilation: { directives: new Set(), pipes: new Set(), }, exported: { directives: new Set(), pipes: new Set(), }, }; maybeUnwrapFn(def.imports).forEach(function (imported) { var importedType = imported; if (!isNgModule(importedType)) { throw new Error("Importing " + importedType.name + " which does not have a \u0275mod property"); } // When this module imports another, the imported module's exported directives and pipes are // added to the compilation scope of this module. var importedScope = transitiveScopesFor(importedType); importedScope.exported.directives.forEach(function (entry) { return scopes.compilation.directives.add(entry); }); importedScope.exported.pipes.forEach(function (entry) { return scopes.compilation.pipes.add(entry); }); }); maybeUnwrapFn(def.declarations).forEach(function (declared) { var declaredWithDefs = declared; if (getPipeDef(declaredWithDefs)) { scopes.compilation.pipes.add(declared); } else { // Either declared has a ɵcmp or ɵdir, or it's a component which hasn't // had its template compiled yet. In either case, it gets added to the compilation's // directives. scopes.compilation.directives.add(declared); } }); maybeUnwrapFn(def.exports).forEach(function (exported) { var exportedType = exported; // Either the type is a module, a pipe, or a component/directive (which may not have a // ɵcmp as it might be compiled asynchronously). if (isNgModule(exportedType)) { // When this module exports another, the exported module's exported directives and pipes are // added to both the compilation and exported scopes of this module. var exportedScope = transitiveScopesFor(exportedType); exportedScope.exported.directives.forEach(function (entry) { scopes.compilation.directives.add(entry); scopes.exported.directives.add(entry); }); exportedScope.exported.pipes.forEach(function (entry) { scopes.compilation.pipes.add(entry); scopes.exported.pipes.add(entry); }); } else if (getPipeDef(exportedType)) { scopes.exported.pipes.add(exportedType); } else { scopes.exported.directives.add(exportedType); } }); def.transitiveCompileScopes = scopes; return scopes; } function expandModuleWithProviders(value) { if (isModuleWithProviders(value)) { return value.ngModule; } return value; } function isModuleWithProviders(value) { return value.ngModule !== undefined; } function isNgModule(value) { return !!getNgModuleDef(value); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvcmVuZGVyMy9qaXQvbW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7QUFFSCxPQUFPLEVBQUMsaUJBQWlCLEVBQTJCLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0YsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDdkQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBSXRELE9BQU8sRUFBQyxXQUFXLEVBQUUsT0FBTyxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sRUFBQyxlQUFlLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDM0YsT0FBTyxFQUFDLFdBQVcsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUczRSxPQUFPLEVBQUMsYUFBYSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFFcEUsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUU3QyxJQUFNLFdBQVcsR0FBZ0IsRUFBRSxDQUFDO0FBT3BDLElBQU0sV0FBVyxHQUFzQixFQUFFLENBQUM7QUFFMUM7OztHQUdHO0FBQ0gsU0FBUyw4QkFBOEIsQ0FBQyxVQUFxQixFQUFFLFFBQWtCO0lBQy9FLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBQyxVQUFVLFlBQUEsRUFBRSxRQUFRLFVBQUEsRUFBQyxDQUFDLENBQUM7QUFDM0MsQ0FBQztBQUVELElBQUksbUJBQW1C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QUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNuQyxDQUFDLENBQUMsQ0FBQztTQUNKO2FBQU0sSUFBSSxVQUFVLENBQUMsWUFBWSxDQUFDLEVBQUU7WUFDbkMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3pDO2FBQU07WUFDTCxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDOUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUM7SUFDckMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQUMsS0FBd0M7SUFDekUsSUFBSSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUNoQyxPQUFPLEtBQUssQ0FBQyxRQUFRLENBQUM7S0FDdkI7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLEtBQVU7SUFDdkMsT0FBUSxLQUEwQixDQUFDLFFBQVEsS0FBSyxTQUFTLENBQUM7QUFDNUQsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFJLEtBQWM7SUFDbkMsT0FBTyxDQUFDLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7Z2V0Q29tcGlsZXJGYWNhZGUsIFIzSW5qZWN0b3JNZXRhZGF0YUZhY2FkZX0gZnJvbSAnLi4vLi4vY29tcGlsZXIvY29tcGlsZXJfZmFjYWRlJztcbmltcG9ydCB7cmVzb2x2ZUZvcndhcmRSZWZ9IGZyb20gJy4uLy4uL2RpL2ZvcndhcmRfcmVmJztcbmltcG9ydCB7TkdfSU5KX0RFRn0gZnJvbSAnLi4vLi4vZGkvaW50ZXJmYWNlL2RlZnMnO1xuaW1wb3J0IHtyZWZsZWN0RGVwZW5kZW5jaWVzfSBmcm9tICcuLi8uLi9kaS9qaXQvdXRpbCc7XG5pbXBvcnQge1R5cGV9IGZyb20gJy4uLy4uL2ludGVyZmFjZS90eXBlJztcbmltcG9ydCB7Q29tcG9uZW50fSBmcm9tICcuLi8uLi9tZXRhZGF0YSc7XG5pbXBvcnQge01vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlLCBOZ01vZHVsZURlZiwgTmdNb2R1bGVUcmFuc2l0aXZlU2NvcGVzfSBmcm9tICcuLi8uLi9tZXRhZGF0YS9uZ19tb2R1bGUnO1xuaW1wb3J0IHtkZWVwRm9yRWFjaCwgZmxhdHRlbn0gZnJvbSAnLi4vLi4vdXRpbC9hcnJheV91dGlscyc7XG5pbXBvcnQge2Fzc2VydERlZmluZWR9IGZyb20gJy4uLy4uL3V0aWwvYXNzZXJ0JztcbmltcG9ydCB7Z2V0Q29tcG9uZW50RGVmLCBnZXREaXJlY3RpdmVEZWYsIGdldE5nTW9kdWxlRGVmLCBnZXRQaXBlRGVmfSBmcm9tICcuLi9kZWZpbml0aW9uJztcbmltcG9ydCB7TkdfQ09NUF9ERUYsIE5HX0RJUl9ERUYsIE5HX01PRF9ERUYsIE5HX1BJUEVfREVGfSBmcm9tICcuLi9maWVsZHMnO1xuaW1wb3J0IHtDb21wb25lbnREZWZ9IGZyb20gJy4uL2ludGVyZmFjZXMvZGVmaW5pdGlvbic7XG5pbXBvcnQge05nTW9kdWxlVHlwZX0gZnJvbSAnLi4vbmdfbW9kdWxlX3JlZic7XG5pbXBvcnQge21heWJlVW53cmFwRm4sIHN0cmluZ2lmeUZvckVycm9yfSBmcm9tICcuLi91dGlsL21pc2NfdXRpbHMnO1xuXG5pbXBvcnQge2FuZ3VsYXJDb3JlRW52fSBmcm9tICcuL2Vudmlyb25tZW50JztcblxuY29uc3QgRU1QVFlfQVJSQVk6IFR5cGU8YW55PltdID0gW107XG5cbmludGVyZmFjZSBNb2R1bGVRdWV1ZUl0ZW0ge1xuICBtb2R1bGVUeXBlOiBUeXBlPGFueT47XG4gIG5nTW9kdWxlOiBOZ01vZHVsZTtcbn1cblxuY29uc3QgbW9kdWxlUXVldWU6IE1vZHVsZVF1ZXVlSXRlbVtdID0gW107XG5cbi8qKlxuICogRW5xdWV1ZXMgbW9kdWxlRGVmIHRvIGJlIGNoZWNrZWQgbGF0ZXIgdG8gc2VlIGlmIHNjb3BlIGNhbiBiZSBzZXQgb24gaXRzXG4gKiBjb21wb25lbnQgZGVjbGFyYXRpb25zLlxuICovXG5mdW5jdGlvbiBlbnF1ZXVlTW9kdWxlRm9yRGVsYXllZFNjb3BpbmcobW9kdWxlVHlwZTogVHlwZTxhbnk+LCBuZ01vZHVsZTogTmdNb2R1bGUpIHtcbiAgbW9kdWxlUXVldWUucHVzaCh7bW9kdWxlVHlwZSwgbmdNb2R1bGV9KTtcbn1cblxubGV0IGZsdXNoaW5nTW9kdWxlUXVldWUgPSBmYWxzZTtcbi8qKlxuICogTG9vcHMgb3ZlciBxdWV1ZWQgbW9kdWxlIGRlZmluaXRpb25zLCBpZiBhIGdpdmVuIG1vZHVsZSBkZWZpbml0aW9uIGhhcyBhbGwgb2YgaXRzXG4gKiBkZWNsYXJhdGlvbnMgcmVzb2x2ZWQsIGl0IGRlcXVldWVzIHRoYXQgbW9kdWxlIGRlZmluaXRpb24gYW5kIHNldHMgdGhlIHNjb3BlIG9uXG4gKiBpdHMgZGVjbGFyYXRpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmx1c2hNb2R1bGVTY29waW5nUXVldWVBc011Y2hBc1Bvc3NpYmxlKCkge1xuICBpZiAoIWZsdXNoaW5nTW9kdWxlUXVldWUpIHtcbiAgICBmbHVzaGluZ01vZHVsZVF1ZXVlID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgZm9yIChsZXQgaSA9IG1vZHVsZVF1ZXVlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IHttb2R1bGVUeXBlLCBuZ01vZHVsZX0gPSBtb2R1bGVRdWV1ZVtpXTtcblxuICAgICAgICBpZiAobmdNb2R1bGUuZGVjbGFyYXRpb25zICYmIG5nTW9kdWxlLmRlY2xhcmF0aW9ucy5ldmVyeShpc1Jlc29sdmVkRGVjbGFyYXRpb24pKSB7XG4gICAgICAgICAgLy8gZGVxdWV1ZVxuICAgICAgICAgIG1vZHVsZVF1ZXVlLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBzZXRTY29wZU9uRGVjbGFyZWRDb21wb25lbnRzKG1vZHVsZVR5cGUsIG5nTW9kdWxlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBmbHVzaGluZ01vZHVsZVF1ZXVlID0gZmFsc2U7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnV0aHkgaWYgYSBkZWNsYXJhdGlvbiBoYXMgcmVzb2x2ZWQuIElmIHRoZSBkZWNsYXJhdGlvbiBoYXBwZW5zIHRvIGJlXG4gKiBhbiBhcnJheSBvZiBkZWNsYXJhdGlvbnMsIGl0IHdpbGwgcmVjdXJzZSB0byBjaGVjayBlYWNoIGRlY2xhcmF0aW9uIGluIHRoYXQgYXJyYXlcbiAqICh3aGljaCBtYXkgYWxzbyBiZSBhcnJheXMpLlxuICovXG5mdW5jdGlvbiBpc1Jlc29sdmVkRGVjbGFyYXRpb24oZGVjbGFyYXRpb246IGFueVtdfFR5cGU8YW55Pik6IGJvb2xlYW4ge1xuICBpZiAoQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbikpIHtcbiAgICByZXR1cm4gZGVjbGFyYXRpb24uZXZlcnkoaXNSZXNvbHZlZERlY2xhcmF0aW9uKTtcbiAgfVxuICByZXR1cm4gISFyZXNvbHZlRm9yd2FyZFJlZihkZWNsYXJhdGlvbik7XG59XG5cbi8qKlxuICogQ29tcGlsZXMgYSBtb2R1bGUgaW4gSklUIG1vZGUuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBhdXRvbWF0aWNhbGx5IGdldHMgY2FsbGVkIHdoZW4gYSBjbGFzcyBoYXMgYSBgQE5nTW9kdWxlYCBkZWNvcmF0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlTmdNb2R1bGUobW9kdWxlVHlwZTogVHlwZTxhbnk+LCBuZ01vZHVsZTogTmdNb2R1bGUgPSB7fSk6IHZvaWQge1xuICBjb21waWxlTmdNb2R1bGVEZWZzKG1vZHVsZVR5cGUgYXMgTmdNb2R1bGVUeXBlLCBuZ01vZHVsZSk7XG5cbiAgLy8gQmVjYXVzZSB3ZSBkb24ndCBrbm93IGlmIGFsbCBkZWNsYXJhdGlvbnMgaGF2ZSByZXNvbHZlZCB5ZXQgYXQgdGhlIG1vbWVudCB0aGVcbiAgLy8gTmdNb2R1bGUgZGVjb3JhdG9yIGlzIGV4ZWN1dGluZywgd2UncmUgZW5xdWV1ZWluZyB0aGUgc2V0dGluZyBvZiBtb2R1bGUgc2NvcGVcbiAgLy8gb24gaXRzIGRlY2xhcmF0aW9ucyB0byBiZSBydW4gYXQgYSBsYXRlciB0aW1lIHdoZW4gYWxsIGRlY2xhcmF0aW9ucyBmb3IgdGhlIG1vZHVsZSxcbiAgLy8gaW5jbHVkaW5nIGZvcndhcmQgcmVmcywgaGF2ZSByZXNvbHZlZC5cbiAgZW5xdWV1ZU1vZHVsZUZvckRlbGF5ZWRTY29waW5nKG1vZHVsZVR5cGUsIG5nTW9kdWxlKTtcbn1cblxuLyoqXG4gKiBDb21waWxlcyBhbmQgYWRkcyB0aGUgYMm1bW9kYCBhbmQgYMm1aW5qYCBwcm9wZXJ0aWVzIHRvIHRoZSBtb2R1bGUgY2xhc3MuXG4gKlxuICogSXQncyBwb3NzaWJsZSB0byBjb21waWxlIGEgbW9kdWxlIHZpYSB0aGlzIEFQSSB3aGljaCB3aWxsIGFsbG93IGR1cGxpY2F0ZSBkZWNsYXJhdGlvbnMgaW4gaXRzXG4gKiByb290LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZU5nTW9kdWxlRGVmcyhcbiAgICBtb2R1bGVUeXBlOiBOZ01vZHVsZVR5cGUsIG5nTW9kdWxlOiBOZ01vZHVsZSxcbiAgICBhbGxvd0R1cGxpY2F0ZURlY2xhcmF0aW9uc0luUm9vdDogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKG1vZHVsZVR5cGUsICdSZXF1aXJlZCB2YWx1ZSBtb2R1bGVUeXBlJyk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKG5nTW9kdWxlLCAnUmVxdWlyZWQgdmFsdWUgbmdNb2R1bGUnKTtcbiAgY29uc3QgZGVjbGFyYXRpb25zOiBUeXBlPGFueT5bXSA9IGZsYXR0ZW4obmdNb2R1bGUuZGVjbGFyYXRpb25zIHx8IEVNUFRZX0FSUkFZKTtcbiAgbGV0IG5nTW9kdWxlRGVmOiBhbnkgPSBudWxsO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlVHlwZSwgTkdfTU9EX0RFRiwge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6ICgpID0+IHtcbiAgICAgIGlmIChuZ01vZHVsZURlZiA9PT0gbnVsbCkge1xuICAgICAgICBpZiAobmdEZXZNb2RlICYmIG5nTW9kdWxlLmltcG9ydHMgJiYgbmdNb2R1bGUuaW1wb3J0cy5pbmRleE9mKG1vZHVsZVR5cGUpID4gLTEpIHtcbiAgICAgICAgICAvLyBXZSBuZWVkIHRvIGFzc2VydCB0aGlzIGltbWVkaWF0ZWx5LCBiZWNhdXNlIGFsbG93aW5nIGl0IHRvIGNvbnRpbnVlIHdpbGwgY2F1c2UgaXQgdG9cbiAgICAgICAgICAvLyBnbyBpbnRvIGFuIGluZmluaXRlIGxvb3AgYmVmb3JlIHdlJ3ZlIHJlYWNoZWQgdGhlIHBvaW50IHdoZXJlIHdlIHRocm93IGFsbCB0aGUgZXJyb3JzLlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJyR7c3RyaW5naWZ5Rm9yRXJyb3IobW9kdWxlVHlwZSl9JyBtb2R1bGUgY2FuJ3QgaW1wb3J0IGl0c2VsZmApO1xuICAgICAgICB9XG4gICAgICAgIG5nTW9kdWxlRGVmID0gZ2V0Q29tcGlsZXJGYWNhZGUoKS5jb21waWxlTmdNb2R1bGUoXG4gICAgICAgICAgICBhbmd1bGFyQ29yZUVudiwgYG5nOi8vLyR7bW9kdWxlVHlwZS5uYW1lfS/JtW1vZC5qc2AsIHtcbiAgICAgICAgICAgICAgdHlwZTogbW9kdWxlVHlwZSxcbiAgICAgICAgICAgICAgYm9vdHN0cmFwOiBmbGF0dGVuKG5nTW9kdWxlLmJvb3RzdHJhcCB8fCBFTVBUWV9BUlJBWSkubWFwKHJlc29sdmVGb3J3YXJkUmVmKSxcbiAgICAgICAgICAgICAgZGVjbGFyYXRpb25zOiBkZWNsYXJhdGlvbnMubWFwKHJlc29sdmVGb3J3YXJkUmVmKSxcbiAgICAgICAgICAgICAgaW1wb3J0czogZmxhdHRlbihuZ01vZHVsZS5pbXBvcnRzIHx8IEVNUFRZX0FSUkFZKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChyZXNvbHZlRm9yd2FyZFJlZilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoZXhwYW5kTW9kdWxlV2l0aFByb3ZpZGVycyksXG4gICAgICAgICAgICAgIGV4cG9ydHM6IGZsYXR0ZW4obmdNb2R1bGUuZXhwb3J0cyB8fCBFTVBUWV9BUlJBWSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAocmVzb2x2ZUZvcndhcmRSZWYpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKGV4cGFuZE1vZHVsZVdpdGhQcm92aWRlcnMpLFxuICAgICAgICAgICAgICBzY2hlbWFzOiBuZ01vZHVsZS5zY2hlbWFzID8gZmxhdHRlbihuZ01vZHVsZS5zY2hlbWFzKSA6IG51bGwsXG4gICAgICAgICAgICAgIGlkOiBuZ01vZHVsZS5pZCB8fCBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIC8vIFNldCBgc2NoZW1hc2Agb24gbmdNb2R1bGVEZWYgdG8gYW4gZW1wdHkgYXJyYXkgaW4gSklUIG1vZGUgdG8gaW5kaWNhdGUgdGhhdCBydW50aW1lXG4gICAgICAgIC8vIHNob3VsZCB2ZXJpZnkgdGhhdCB0aGVyZSBhcmUgbm8gdW5rbm93biBlbGVtZW50cyBpbiBhIHRlbXBsYXRlLiBJbiBBT1QgbW9kZSwgdGhhdCBjaGVja1xuICAgICAgICAvLyBoYXBwZW5zIGF0IGNvbXBpbGUgdGltZSBhbmQgYHNjaGVtYXNgIGluZm9ybWF0aW9uIGlzIG5vdCBwcmVzZW50IG9uIENvbXBvbmVudCBhbmQgTW9kdWxlXG4gICAgICAgIC8vIGRlZnMgYWZ0ZXIgY29tcGlsYXRpb24gKHNvIHRoZSBjaGVjayBkb2Vzbid0IGhhcHBlbiB0aGUgc2Vjb25kIHRpbWUgYXQgcnVudGltZSkuXG4gICAgICAgIGlmICghbmdNb2R1bGVEZWYuc2NoZW1hcykge1xuICAgICAgICAgIG5nTW9kdWxlRGVmLnNjaGVtYXMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5nTW9kdWxlRGVmO1xuICAgIH1cbiAgfSk7XG5cbiAgbGV0IG5nSW5qZWN0b3JEZWY6IGFueSA9IG51bGw7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGVUeXBlLCBOR19JTkpfREVGLCB7XG4gICAgZ2V0OiAoKSA9PiB7XG4gICAgICBpZiAobmdJbmplY3RvckRlZiA9PT0gbnVsbCkge1xuICAgICAgICBuZ0Rldk1vZGUgJiZcbiAgICAgICAgICAgIHZlcmlmeVNlbWFudGljc09mTmdNb2R1bGVEZWYoXG4gICAgICAgICAgICAgICAgbW9kdWxlVHlwZSBhcyBhbnkgYXMgTmdNb2R1bGVUeXBlLCBhbGxvd0R1cGxpY2F0ZURlY2xhcmF0aW9uc0luUm9vdCk7XG4gICAgICAgIGNvbnN0IG1ldGE6IFIzSW5qZWN0b3JNZXRhZGF0YUZhY2FkZSA9IHtcbiAgICAgICAgICBuYW1lOiBtb2R1bGVUeXBlLm5hbWUsXG4gICAgICAgICAgdHlwZTogbW9kdWxlVHlwZSxcbiAgICAgICAgICBkZXBzOiByZWZsZWN0RGVwZW5kZW5jaWVzKG1vZHVsZVR5cGUpLFxuICAgICAgICAgIHByb3ZpZGVyczogbmdNb2R1bGUucHJvdmlkZXJzIHx8IEVNUFRZX0FSUkFZLFxuICAgICAgICAgIGltcG9ydHM6IFtcbiAgICAgICAgICAgIChuZ01vZHVsZS5pbXBvcnRzIHx8IEVNUFRZX0FSUkFZKS5tYXAocmVzb2x2ZUZvcndhcmRSZWYpLFxuICAgICAgICAgICAgKG5nTW9kdWxlLmV4cG9ydHMgfHwgRU1QVFlfQVJSQVkpLm1hcChyZXNvbHZlRm9yd2FyZFJlZiksXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgbmdJbmplY3RvckRlZiA9IGdldENvbXBpbGVyRmFjYWRlKCkuY29tcGlsZUluamVjdG9yKFxuICAgICAgICAgICAgYW5ndWxhckNvcmVFbnYsIGBuZzovLy8ke21vZHVsZVR5cGUubmFtZX0vybVpbmouanNgLCBtZXRhKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZ0luamVjdG9yRGVmO1xuICAgIH0sXG4gICAgLy8gTWFrZSB0aGUgcHJvcGVydHkgY29uZmlndXJhYmxlIGluIGRldiBtb2RlIHRvIGFsbG93IG92ZXJyaWRpbmcgaW4gdGVzdHNcbiAgICBjb25maWd1cmFibGU6ICEhbmdEZXZNb2RlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gdmVyaWZ5U2VtYW50aWNzT2ZOZ01vZHVsZURlZihcbiAgICBtb2R1bGVUeXBlOiBOZ01vZHVsZVR5cGUsIGFsbG93RHVwbGljYXRlRGVjbGFyYXRpb25zSW5Sb290OiBib29sZWFuLFxuICAgIGltcG9ydGluZ01vZHVsZT86IE5nTW9kdWxlVHlwZSk6IHZvaWQge1xuICBpZiAodmVyaWZpZWROZ01vZHVsZS5nZXQobW9kdWxlVHlwZSkpIHJldHVybjtcbiAgdmVyaWZpZWROZ01vZHVsZS5zZXQobW9kdWxlVHlwZSwgdHJ1ZSk7XG4gIG1vZHVsZVR5cGUgPSByZXNvbHZlRm9yd2F