UNPKG

@angular/core

Version:

Angular - the core framework

681 lines 73.9 kB
/** * @fileoverview added by tsickle * Generated from: packages/core/src/render3/jit/module.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @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 { 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'; /** @type {?} */ const EMPTY_ARRAY = []; /** * @record */ function ModuleQueueItem() { } if (false) { /** @type {?} */ ModuleQueueItem.prototype.moduleType; /** @type {?} */ ModuleQueueItem.prototype.ngModule; } /** @type {?} */ const moduleQueue = []; /** * Enqueues moduleDef to be checked later to see if scope can be set on its * component declarations. * @param {?} moduleType * @param {?} ngModule * @return {?} */ function enqueueModuleForDelayedScoping(moduleType, ngModule) { moduleQueue.push({ moduleType, ngModule }); } /** @type {?} */ let 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. * @return {?} */ export function flushModuleScopingQueueAsMuchAsPossible() { if (!flushingModuleQueue) { flushingModuleQueue = true; try { for (let i = moduleQueue.length - 1; i >= 0; i--) { const { moduleType, ngModule } = moduleQueue[i]; 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). * @param {?} declaration * @return {?} */ 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. * @param {?} moduleType * @param {?=} ngModule * @return {?} */ export function compileNgModule(moduleType, ngModule = {}) { compileNgModuleDefs((/** @type {?} */ (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. * @param {?} moduleType * @param {?} ngModule * @param {?=} allowDuplicateDeclarationsInRoot * @return {?} */ export function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot = false) { ngDevMode && assertDefined(moduleType, 'Required value moduleType'); ngDevMode && assertDefined(ngModule, 'Required value ngModule'); /** @type {?} */ const declarations = flatten(ngModule.declarations || EMPTY_ARRAY); /** @type {?} */ let ngModuleDef = null; Object.defineProperty(moduleType, NG_MOD_DEF, { configurable: true, get: (/** * @return {?} */ () => { 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}/ɵmod.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; }) }); /** @type {?} */ let ngInjectorDef = null; Object.defineProperty(moduleType, NG_INJ_DEF, { get: (/** * @return {?} */ () => { if (ngInjectorDef === null) { ngDevMode && verifySemanticsOfNgModuleDef((/** @type {?} */ ((/** @type {?} */ (moduleType)))), allowDuplicateDeclarationsInRoot); /** @type {?} */ const 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}/ɵinj.js`, meta); } return ngInjectorDef; }), // Make the property configurable in dev mode to allow overriding in tests configurable: !!ngDevMode, }); } /** * @param {?} moduleType * @param {?} allowDuplicateDeclarationsInRoot * @param {?=} importingModule * @return {?} */ function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) { if (verifiedNgModule.get(moduleType)) return; verifiedNgModule.set(moduleType, true); moduleType = resolveForwardRef(moduleType); /** @type {?} */ let ngModuleDef; if (importingModule) { ngModuleDef = (/** @type {?} */ (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); } /** @type {?} */ const errors = []; /** @type {?} */ const declarations = maybeUnwrapFn(ngModuleDef.declarations); /** @type {?} */ const imports = maybeUnwrapFn(ngModuleDef.imports); flatten(imports).map(unwrapModuleWithProvidersImports).forEach((/** * @param {?} mod * @return {?} */ mod => { verifySemanticsOfNgModuleImport(mod, moduleType); verifySemanticsOfNgModuleDef(mod, false, moduleType); })); /** @type {?} */ const exports = maybeUnwrapFn(ngModuleDef.exports); declarations.forEach(verifyDeclarationsHaveDefinitions); declarations.forEach(verifyDirectivesHaveSelector); /** @type {?} */ const combinedDeclarations = [ ...declarations.map(resolveForwardRef), ...flatten(imports.map(computeCombinedExports)).map(resolveForwardRef), ]; exports.forEach(verifyExportsAreDeclaredOrReExported); declarations.forEach((/** * @param {?} decl * @return {?} */ decl => verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot))); declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule); /** @type {?} */ const ngModule = getAnnotation(moduleType, 'NgModule'); if (ngModule) { ngModule.imports && flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach((/** * @param {?} mod * @return {?} */ 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')); } //////////////////////////////////////////////////////////////////////////////////////////////// /** * @param {?} type * @return {?} */ function verifyDeclarationsHaveDefinitions(type) { type = resolveForwardRef(type); /** @type {?} */ const 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.`); } } /** * @param {?} type * @return {?} */ function verifyDirectivesHaveSelector(type) { type = resolveForwardRef(type); /** @type {?} */ const def = getDirectiveDef(type); if (!getComponentDef(type) && def && def.selectors.length == 0) { errors.push(`Directive ${stringifyForError(type)} has no selector, please add it!`); } } /** * @param {?} type * @return {?} */ function verifyExportsAreDeclaredOrReExported(type) { type = resolveForwardRef(type); /** @type {?} */ const 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!`); } } } /** * @param {?} type * @param {?} suppressErrors * @return {?} */ function verifyDeclarationIsUnique(type, suppressErrors) { type = resolveForwardRef(type); /** @type {?} */ const existingModule = ownerNgModule.get(type); if (existingModule && existingModule !== moduleType) { if (!suppressErrors) { /** @type {?} */ const 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); } } /** * @param {?} type * @return {?} */ function verifyComponentIsPartOfNgModule(type) { type = resolveForwardRef(type); /** @type {?} */ const 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.`); } } /** * @param {?} type * @return {?} */ function verifyCorrectBootstrapType(type) { type = resolveForwardRef(type); if (!getComponentDef(type)) { errors.push(`${stringifyForError(type)} cannot be used as an entry component.`); } } /** * @param {?} type * @return {?} */ function verifyComponentEntryComponentsIsPartOfNgModule(type) { type = resolveForwardRef(type); if (getComponentDef(type)) { // We know we are component /** @type {?} */ const component = getAnnotation(type, 'Component'); if (component && component.entryComponents) { deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule); } } } /** * @param {?} type * @param {?} importingModule * @return {?} */ 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.`); } } } /** * @param {?} typeOrWithProviders * @return {?} */ function unwrapModuleWithProvidersImports(typeOrWithProviders) { typeOrWithProviders = resolveForwardRef(typeOrWithProviders); return ((/** @type {?} */ (typeOrWithProviders))).ngModule || typeOrWithProviders; } /** * @template T * @param {?} type * @param {?} name * @return {?} */ function getAnnotation(type, name) { /** @type {?} */ let annotation = null; collect(type.__annotations__); collect(type.decorators); return annotation; /** * @param {?} annotations * @return {?} */ function collect(annotations) { if (annotations) { annotations.forEach(readAnnotation); } } /** * @param {?} decorator * @return {?} */ function readAnnotation(decorator) { if (!annotation) { /** @type {?} */ const proto = Object.getPrototypeOf(decorator); if (proto.ngMetadataName == name) { annotation = (/** @type {?} */ (decorator)); } else if (decorator.type) { /** @type {?} */ const proto = Object.getPrototypeOf(decorator.type); if (proto.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. * @type {?} */ let ownerNgModule = new Map(); /** @type {?} */ let verifiedNgModule = new Map(); /** * @return {?} */ 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 * @return {?} */ function computeCombinedExports(type) { type = resolveForwardRef(type); /** @type {?} */ const ngModuleDef = getNgModuleDef(type, true); return [...flatten(maybeUnwrapFn(ngModuleDef.exports).map((/** * @param {?} type * @return {?} */ (type) => { /** @type {?} */ const ngModuleDef = getNgModuleDef(type); if (ngModuleDef) { verifySemanticsOfNgModuleDef((/** @type {?} */ ((/** @type {?} */ (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. * @param {?} moduleType * @param {?} ngModule * @return {?} */ function setScopeOnDeclaredComponents(moduleType, ngModule) { /** @type {?} */ const declarations = flatten(ngModule.declarations || EMPTY_ARRAY); /** @type {?} */ const transitiveScopes = transitiveScopesFor(moduleType); declarations.forEach((/** * @param {?} declaration * @return {?} */ declaration => { if (declaration.hasOwnProperty(NG_COMP_DEF)) { // A `ɵcmp` field exists - go ahead and patch the component directly. /** @type {?} */ const component = (/** @type {?} */ (declaration)); /** @type {?} */ const componentDef = (/** @type {?} */ (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. ((/** @type {?} */ (declaration))).ngSelectorScope = moduleType; } })); } /** * Patch the definition of a component with directives and pipes from the compilation scope of * a given module. * @template C * @param {?} componentDef * @param {?} transitiveScopes * @return {?} */ export function patchComponentDefWithScope(componentDef, transitiveScopes) { componentDef.directiveDefs = (/** * @return {?} */ () => Array.from(transitiveScopes.compilation.directives) .map((/** * @param {?} dir * @return {?} */ dir => dir.hasOwnProperty(NG_COMP_DEF) ? (/** @type {?} */ (getComponentDef(dir))) : (/** @type {?} */ (getDirectiveDef(dir))))) .filter((/** * @param {?} def * @return {?} */ def => !!def))); componentDef.pipeDefs = (/** * @return {?} */ () => Array.from(transitiveScopes.compilation.pipes).map((/** * @param {?} pipe * @return {?} */ pipe => (/** @type {?} */ (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. * * @template T * @param {?} moduleType module that transitive scope should be calculated for. * @return {?} */ export function transitiveScopesFor(moduleType) { if (!isNgModule(moduleType)) { throw new Error(`${moduleType.name} does not have a module def (ɵmod property)`); } /** @type {?} */ const def = (/** @type {?} */ (getNgModuleDef(moduleType))); if (def.transitiveCompileScopes !== null) { return def.transitiveCompileScopes; } /** @type {?} */ const scopes = { schemas: def.schemas || null, compilation: { directives: new Set(), pipes: new Set(), }, exported: { directives: new Set(), pipes: new Set(), }, }; maybeUnwrapFn(def.imports).forEach((/** * @template I * @param {?} imported * @return {?} */ (imported) => { /** @type {?} */ const importedType = (/** @type {?} */ (imported)); if (!isNgModule(importedType)) { throw new Error(`Importing ${importedType.name} which does not have a ɵmod property`); } // When this module imports another, the imported module's exported directives and pipes are // added to the compilation scope of this module. /** @type {?} */ const importedScope = transitiveScopesFor(importedType); importedScope.exported.directives.forEach((/** * @param {?} entry * @return {?} */ entry => scopes.compilation.directives.add(entry))); importedScope.exported.pipes.forEach((/** * @param {?} entry * @return {?} */ entry => scopes.compilation.pipes.add(entry))); })); maybeUnwrapFn(def.declarations).forEach((/** * @param {?} declared * @return {?} */ declared => { /** @type {?} */ const declaredWithDefs = (/** @type {?} */ (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((/** * @template E * @param {?} exported * @return {?} */ (exported) => { /** @type {?} */ const exportedType = (/** @type {?} */ (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. /** @type {?} */ const exportedScope = transitiveScopesFor(exportedType); exportedScope.exported.directives.forEach((/** * @param {?} entry * @return {?} */ entry => { scopes.compilation.directives.add(entry); scopes.exported.directives.add(entry); })); exportedScope.exported.pipes.forEach((/** * @param {?} entry * @return {?} */ 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; } /** * @param {?} value * @return {?} */ function expandModuleWithProviders(value) { if (isModuleWithProviders(value)) { return value.ngModule; } return value; } /** * @param {?} value * @return {?} */ function isModuleWithProviders(value) { return ((/** @type {?} */ (value))).ngModule !== undefined; } /** * @template T * @param {?} value * @return {?} */ function isNgModule(value) { return !!getNgModuleDef(value); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvcmVuZGVyMy9qaXQvbW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBMkIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFJdEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMzRixPQUFPLEVBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBRzNFLE9BQU8sRUFBQyxhQUFhLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZUFBZSxDQUFDOztNQUV2QyxXQUFXLEdBQWdCLEVBQUU7Ozs7QUFFbkMsOEJBR0M7OztJQUZDLHFDQUFzQjs7SUFDdEIsbUNBQW1COzs7TUFHZixXQUFXLEdBQXNCLEVBQUU7Ozs7Ozs7O0FBTXpDLFNBQVMsOEJBQThCLENBQUMsVUFBcUIsRUFBRSxRQUFrQjtJQUMvRSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUMsVUFBVSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7QUFDM0MsQ0FBQzs7SUFFRyxtQkFBbUIsR0FBRyxL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SUFBSSxVQUFVLENBQUMsWUFBWSxDQUFDLEVBQUU7WUFDbkMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3pDO2FBQU07WUFDTCxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDOUM7SUFDSCxDQUFDLEVBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUM7SUFDckMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQzs7Ozs7QUFFRCxTQUFTLHlCQUF5QixDQUFDLEtBQXdDO0lBQ3pFLElBQUkscUJBQXFCLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDaEMsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDO0tBQ3ZCO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDOzs7OztBQUVELFNBQVMscUJBQXFCLENBQUMsS0FBVTtJQUN2QyxPQUFPLENBQUMsbUJBQUEsS0FBSyxFQUFvQixDQUFDLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQztBQUM1RCxDQUFDOzs7Ozs7QUFFRCxTQUFTLFVBQVUsQ0FBSSxLQUFjO0lBQ25DLE9BQU8sQ0FBQyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge2dldENvbXBpbGVyRmFjYWRlLCBSM0luamVjdG9yTWV0YWRhdGFGYWNhZGV9IGZyb20gJy4uLy4uL2NvbXBpbGVyL2NvbXBpbGVyX2ZhY2FkZSc7XG5pbXBvcnQge3Jlc29sdmVGb3J3YXJkUmVmfSBmcm9tICcuLi8uLi9kaS9mb3J3YXJkX3JlZic7XG5pbXBvcnQge05HX0lOSl9ERUZ9IGZyb20gJy4uLy4uL2RpL2ludGVyZmFjZS9kZWZzJztcbmltcG9ydCB7cmVmbGVjdERlcGVuZGVuY2llc30gZnJvbSAnLi4vLi4vZGkvaml0L3V0aWwnO1xuaW1wb3J0IHtUeXBlfSBmcm9tICcuLi8uLi9pbnRlcmZhY2UvdHlwZSc7XG5pbXBvcnQge0NvbXBvbmVudH0gZnJvbSAnLi4vLi4vbWV0YWRhdGEnO1xuaW1wb3J0IHtNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSwgTmdNb2R1bGVEZWYsIE5nTW9kdWxlVHJhbnNpdGl2ZVNjb3Blc30gZnJvbSAnLi4vLi4vbWV0YWRhdGEvbmdfbW9kdWxlJztcbmltcG9ydCB7ZGVlcEZvckVhY2gsIGZsYXR0ZW59IGZyb20gJy4uLy4uL3V0aWwvYXJyYXlfdXRpbHMnO1xuaW1wb3J0IHthc3NlcnREZWZpbmVkfSBmcm9tICcuLi8uLi91dGlsL2Fzc2VydCc7XG5pbXBvcnQge2dldENvbXBvbmVudERlZiwgZ2V0RGlyZWN0aXZlRGVmLCBnZXROZ01vZHVsZURlZiwgZ2V0UGlwZURlZn0gZnJvbSAnLi4vZGVmaW5pdGlvbic7XG5pbXBvcnQge05HX0NPTVBfREVGLCBOR19ESVJfREVGLCBOR19NT0RfREVGLCBOR19QSVBFX0RFRn0gZnJvbSAnLi4vZmllbGRzJztcbmltcG9ydCB7Q29tcG9uZW50RGVmfSBmcm9tICcuLi9pbnRlcmZhY2VzL2RlZmluaXRpb24nO1xuaW1wb3J0IHtOZ01vZHVsZVR5cGV9IGZyb20gJy4uL25nX21vZHVsZV9yZWYnO1xuaW1wb3J0IHttYXliZVVud3JhcEZuLCBzdHJpbmdpZnlGb3JFcnJvcn0gZnJvbSAnLi4vdXRpbC9taXNjX3V0aWxzJztcblxuaW1wb3J0IHthbmd1bGFyQ29yZUVudn0gZnJvbSAnLi9lbnZpcm9ubWVudCc7XG5cbmNvbnN0IEVNUFRZX0FSUkFZOiBUeXBlPGFueT5bXSA9IFtdO1xuXG5pbnRlcmZhY2UgTW9kdWxlUXVldWVJdGVtIHtcbiAgbW9kdWxlVHlwZTogVHlwZTxhbnk+O1xuICBuZ01vZHVsZTogTmdNb2R1bGU7XG59XG5cbmNvbnN0IG1vZHVsZVF1ZXVlOiBNb2R1bGVRdWV1ZUl0ZW1bXSA9IFtdO1xuXG4vKipcbiAqIEVucXVldWVzIG1vZHVsZURlZiB0byBiZSBjaGVja2VkIGxhdGVyIHRvIHNlZSBpZiBzY29wZSBjYW4gYmUgc2V0IG9uIGl0c1xuICogY29tcG9uZW50IGRlY2xhcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZU1vZHVsZUZvckRlbGF5ZWRTY29waW5nKG1vZHVsZVR5cGU6IFR5cGU8YW55PiwgbmdNb2R1bGU6IE5nTW9kdWxlKSB7XG4gIG1vZHVsZVF1ZXVlLnB1c2goe21vZHVsZVR5cGUsIG5nTW9kdWxlfSk7XG59XG5cbmxldCBmbHVzaGluZ01vZHVsZVF1ZXVlID0gZmFsc2U7XG4vKipcbiAqIExvb3BzIG92ZXIgcXVldWVkIG1vZHVsZSBkZWZpbml0aW9ucywgaWYgYSBnaXZlbiBtb2R1bGUgZGVmaW5pdGlvbiBoYXMgYWxsIG9mIGl0c1xuICogZGVjbGFyYXRpb25zIHJlc29sdmVkLCBpdCBkZXF1ZXVlcyB0aGF0IG1vZHVsZSBkZWZpbml0aW9uIGFuZCBzZXRzIHRoZSBzY29wZSBvblxuICogaXRzIGRlY2xhcmF0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsdXNoTW9kdWxlU2NvcGluZ1F1ZXVlQXNNdWNoQXNQb3NzaWJsZSgpIHtcbiAgaWYgKCFmbHVzaGluZ01vZHVsZVF1ZXVlKSB7XG4gICAgZmx1c2hpbmdNb2R1bGVRdWV1ZSA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGZvciAobGV0IGkgPSBtb2R1bGVRdWV1ZS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCB7bW9kdWxlVHlwZSwgbmdNb2R1bGV9ID0gbW9kdWxlUXVldWVbaV07XG5cbiAgICAgICAgaWYgKG5nTW9kdWxlLmRlY2xhcmF0aW9ucyAmJiBuZ01vZHVsZS5kZWNsYXJhdGlvbnMuZXZlcnkoaXNSZXNvbHZlZERlY2xhcmF0aW9uKSkge1xuICAgICAgICAgIC8vIGRlcXVldWVcbiAgICAgICAgICBtb2R1bGVRdWV1ZS5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgc2V0U2NvcGVPbkRlY2xhcmVkQ29tcG9uZW50cyhtb2R1bGVUeXBlLCBuZ01vZHVsZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgZmx1c2hpbmdNb2R1bGVRdWV1ZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1dGh5IGlmIGEgZGVjbGFyYXRpb24gaGFzIHJlc29sdmVkLiBJZiB0aGUgZGVjbGFyYXRpb24gaGFwcGVucyB0byBiZVxuICogYW4gYXJyYXkgb2YgZGVjbGFyYXRpb25zLCBpdCB3aWxsIHJlY3Vyc2UgdG8gY2hlY2sgZWFjaCBkZWNsYXJhdGlvbiBpbiB0aGF0IGFycmF5XG4gKiAod2hpY2ggbWF5IGFsc28gYmUgYXJyYXlzKS5cbiAqL1xuZnVuY3Rpb24gaXNSZXNvbHZlZERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uOiBhbnlbXXxUeXBlPGFueT4pOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24pKSB7XG4gICAgcmV0dXJuIGRlY2xhcmF0aW9uLmV2ZXJ5KGlzUmVzb2x2ZWREZWNsYXJhdGlvbik7XG4gIH1cbiAgcmV0dXJuICEhcmVzb2x2ZUZvcndhcmRSZWYoZGVjbGFyYXRpb24pO1xufVxuXG4vKipcbiAqIENvbXBpbGVzIGEgbW9kdWxlIGluIEpJVCBtb2RlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gYXV0b21hdGljYWxseSBnZXRzIGNhbGxlZCB3aGVuIGEgY2xhc3MgaGFzIGEgYEBOZ01vZHVsZWAgZGVjb3JhdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZU5nTW9kdWxlKG1vZHVsZVR5cGU6IFR5cGU8YW55PiwgbmdNb2R1bGU6IE5nTW9kdWxlID0ge30pOiB2b2lkIHtcbiAgY29tcGlsZU5nTW9kdWxlRGVmcyhtb2R1bGVUeXBlIGFzIE5nTW9kdWxlVHlwZSwgbmdNb2R1bGUpO1xuXG4gIC8vIEJlY2F1c2Ugd2UgZG9uJ3Qga25vdyBpZiBhbGwgZGVjbGFyYXRpb25zIGhhdmUgcmVzb2x2ZWQgeWV0IGF0IHRoZSBtb21lbnQgdGhlXG4gIC8vIE5nTW9kdWxlIGRlY29yYXRvciBpcyBleGVjdXRpbmcsIHdlJ3JlIGVucXVldWVpbmcgdGhlIHNldHRpbmcgb2YgbW9kdWxlIHNjb3BlXG4gIC8vIG9uIGl0cyBkZWNsYXJhdGlvbnMgdG8gYmUgcnVuIGF0IGEgbGF0ZXIgdGltZSB3aGVuIGFsbCBkZWNsYXJhdGlvbnMgZm9yIHRoZSBtb2R1bGUsXG4gIC8vIGluY2x1ZGluZyBmb3J3YXJkIHJlZnMsIGhhdmUgcmVzb2x2ZWQuXG4gIGVucXVldWVNb2R1bGVGb3JEZWxheWVkU2NvcGluZyhtb2R1bGVUeXBlLCBuZ01vZHVsZSk7XG59XG5cbi8qKlxuICogQ29tcGlsZXMgYW5kIGFkZHMgdGhlIGDJtW1vZGAgYW5kIGDJtWluamAgcHJvcGVydGllcyB0byB0aGUgbW9kdWxlIGNsYXNzLlxuICpcbiAqIEl0J3MgcG9zc2libGUgdG8gY29tcGlsZSBhIG1vZHVsZSB2aWEgdGhpcyBBUEkgd2hpY2ggd2lsbCBhbGxvdyBkdXBsaWNhdGUgZGVjbGFyYXRpb25zIGluIGl0c1xuICogcm9vdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVOZ01vZHVsZURlZnMoXG4gICAgbW9kdWxlVHlwZTogTmdNb2R1bGVUeXBlLCBuZ01vZHVsZTogTmdNb2R1bGUsXG4gICAgYWxsb3dEdXBsaWNhdGVEZWNsYXJhdGlvbnNJblJvb3Q6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZChtb2R1bGVUeXBlLCAnUmVxdWlyZWQgdmFsdWUgbW9kdWxlVHlwZScpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZChuZ01vZHVsZSwgJ1JlcXVpcmVkIHZhbHVlIG5nTW9kdWxlJyk7XG4gIGNvbnN0IGRlY2xhcmF0aW9uczogVHlwZTxhbnk+W10gPSBmbGF0dGVuKG5nTW9kdWxlLmRlY2xhcmF0aW9ucyB8fCBFTVBUWV9BUlJBWSk7XG4gIGxldCBuZ01vZHVsZURlZjogYW55ID0gbnVsbDtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZVR5cGUsIE5HX01PRF9ERUYsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiAoKSA9PiB7XG4gICAgICBpZiAobmdNb2R1bGVEZWYgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKG5nRGV2TW9kZSAmJiBuZ01vZHVsZS5pbXBvcnRzICYmIG5nTW9kdWxlLmltcG9y