oidc-client
Version:
OpenID Connect (OIDC) & OAuth2 client library
663 lines • 97 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @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
*/
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const tasks_1 = require("@angular-devkit/schematics/tasks");
const dependencies_1 = require("../../utility/dependencies");
const json_utils_1 = require("../../utility/json-utils");
const latest_versions_1 = require("../../utility/latest-versions");
const defaults = {
appRoot: 'src',
index: 'index.html',
main: 'main.ts',
polyfills: 'polyfills.ts',
tsConfig: 'tsconfig.app.json',
test: 'test.ts',
outDir: 'dist/',
karma: 'karma.conf.js',
protractor: 'protractor.conf.js',
testTsConfig: 'tsconfig.spec.json',
serverOutDir: 'dist-server',
serverMain: 'main.server.ts',
serverTsConfig: 'tsconfig.server.json',
};
function getConfigPath(tree) {
let possiblePath = core_1.normalize('.angular-cli.json');
if (tree.exists(possiblePath)) {
return possiblePath;
}
possiblePath = core_1.normalize('angular-cli.json');
if (tree.exists(possiblePath)) {
return possiblePath;
}
throw new schematics_1.SchematicsException('Could not find configuration file');
}
function migrateKarmaConfiguration(config) {
return (host, context) => {
context.logger.info(`Updating karma configuration`);
try {
const karmaPath = config && config.test && config.test.karma && config.test.karma.config
? config.test.karma.config
: defaults.karma;
const buffer = host.read(karmaPath);
if (buffer !== null) {
let content = buffer.toString();
// Replace the 1.0 files and preprocessor entries, with and without comma at the end.
// If these remain, they will cause the `ng test` to fail.
content = content.replace(`{ pattern: './src/test.ts', watched: false },`, '');
content = content.replace(`{ pattern: './src/test.ts', watched: false }`, '');
content = content.replace(`'./src/test.ts': ['@angular/cli'],`, '');
content = content.replace(`'./src/test.ts': ['@angular/cli']`, '');
content = content.replace(/angularCli[^}]*},?/, '');
// Replace 1.x plugin names.
content = content.replace(/@angular\/cli/g, '@angular-devkit/build-angular');
// Replace code coverage output path.
content = content.replace('reports', `dir: require('path').join(__dirname, 'coverage'), reports`);
host.overwrite(karmaPath, content);
}
}
catch (_a) { }
return host;
};
}
function migrateConfiguration(oldConfig, logger) {
return (host, context) => {
const oldConfigPath = getConfigPath(host);
const configPath = core_1.normalize('angular.json');
context.logger.info(`Updating configuration`);
const config = {
'$schema': './node_modules/@angular/cli/lib/config/schema.json',
version: 1,
newProjectRoot: 'projects',
projects: extractProjectsConfig(oldConfig, host, logger),
};
const defaultProject = extractDefaultProject(oldConfig);
if (defaultProject !== null) {
config.defaultProject = defaultProject;
}
const cliConfig = extractCliConfig(oldConfig);
if (cliConfig !== null) {
config.cli = cliConfig;
}
const schematicsConfig = extractSchematicsConfig(oldConfig);
if (schematicsConfig !== null) {
config.schematics = schematicsConfig;
}
const targetsConfig = extractTargetsConfig(oldConfig);
if (targetsConfig !== null) {
config.architect = targetsConfig;
}
context.logger.info(`Removing old config file (${oldConfigPath})`);
host.delete(oldConfigPath);
context.logger.info(`Writing config file (${configPath})`);
host.create(configPath, JSON.stringify(config, null, 2));
return host;
};
}
function extractCliConfig(config) {
const newConfig = {};
if (config.packageManager && config.packageManager !== 'default') {
newConfig['packageManager'] = config.packageManager;
}
if (config.warnings) {
if (config.warnings.versionMismatch !== undefined) {
newConfig.warnings = Object.assign({}, (newConfig.warnings || {}), { versionMismatch: config.warnings.versionMismatch });
}
if (config.warnings.typescriptMismatch !== undefined) {
newConfig.warnings = Object.assign({}, (newConfig.warnings || {}), { typescriptMismatch: config.warnings.typescriptMismatch });
}
}
return Object.getOwnPropertyNames(newConfig).length == 0 ? null : newConfig;
}
function extractSchematicsConfig(config) {
let collectionName = '@schematics/angular';
if (!config || !config.defaults) {
return null;
}
// const configDefaults = config.defaults;
if (config.defaults && config.defaults.schematics && config.defaults.schematics.collection) {
collectionName = config.defaults.schematics.collection;
}
/**
* For each schematic
* - get the config
* - filter one's without config
* - combine them into an object
*/
// tslint:disable-next-line:no-any
const schematicConfigs = ['class', 'component', 'directive', 'guard',
'interface', 'module', 'pipe', 'service']
.map(schematicName => {
// tslint:disable-next-line:no-any
const schematicDefaults = config.defaults[schematicName] || null;
return {
schematicName,
config: schematicDefaults,
};
})
.filter(schematic => schematic.config !== null)
.reduce((all, schematic) => {
all[collectionName + ':' + schematic.schematicName] = schematic.config;
return all;
}, {});
const componentUpdate = {};
componentUpdate.prefix = '';
const componentKey = collectionName + ':component';
const directiveKey = collectionName + ':directive';
if (!schematicConfigs[componentKey]) {
schematicConfigs[componentKey] = {};
}
if (!schematicConfigs[directiveKey]) {
schematicConfigs[directiveKey] = {};
}
if (config.apps && config.apps[0]) {
schematicConfigs[componentKey].prefix = config.apps[0].prefix;
schematicConfigs[directiveKey].prefix = config.apps[0].prefix;
}
if (config.defaults) {
schematicConfigs[componentKey].styleext = config.defaults.styleExt;
}
return schematicConfigs;
}
function extractTargetsConfig(_config) {
return null;
}
// This function is too big, but also really hard to refactor properly as the whole config
// depends on all parts of the config.
// tslint:disable-next-line:no-big-function
function extractProjectsConfig(config, tree, logger) {
const builderPackage = '@angular-devkit/build-angular';
const defaultAppNamePrefix = getDefaultAppNamePrefix(config);
const buildDefaults = config.defaults && config.defaults.build
? {
sourceMap: config.defaults.build.sourcemaps,
progress: config.defaults.build.progress,
poll: config.defaults.build.poll,
deleteOutputPath: config.defaults.build.deleteOutputPath,
preserveSymlinks: config.defaults.build.preserveSymlinks,
showCircularDependencies: config.defaults.build.showCircularDependencies,
commonChunk: config.defaults.build.commonChunk,
namedChunks: config.defaults.build.namedChunks,
}
: {};
const serveDefaults = config.defaults && config.defaults.serve
? {
port: config.defaults.serve.port,
host: config.defaults.serve.host,
ssl: config.defaults.serve.ssl,
sslKey: config.defaults.serve.sslKey,
sslCert: config.defaults.serve.sslCert,
proxyConfig: config.defaults.serve.proxyConfig,
}
: {};
const apps = config.apps || [];
// convert the apps to projects
const browserApps = apps.filter(app => app.platform !== 'server');
const serverApps = apps.filter(app => app.platform === 'server');
const projectMap = browserApps
// This function is too big, but also really hard to refactor properly as the whole config
// depends on all parts of the config.
// tslint:disable-next-line:no-big-function
.map((app, idx) => {
const defaultAppName = idx === 0 ? defaultAppNamePrefix : `${defaultAppNamePrefix}${idx}`;
const name = app.name || defaultAppName;
const outDir = app.outDir || defaults.outDir;
const appRoot = app.root || defaults.appRoot;
function _mapAssets(asset) {
if (typeof asset === 'string') {
return core_1.normalize(appRoot + '/' + asset);
}
else {
if (asset.allowOutsideOutDir) {
logger.warn(core_1.tags.oneLine `
Asset with input '${asset.input}' was not migrated because it
uses the 'allowOutsideOutDir' option which is not supported in Angular CLI 6.
`);
return null;
}
else if (asset.output) {
return {
glob: asset.glob,
input: core_1.normalize(appRoot + '/' + asset.input),
output: core_1.normalize('/' + asset.output),
};
}
else {
return {
glob: asset.glob,
input: core_1.normalize(appRoot + '/' + asset.input),
output: '/',
};
}
}
}
function _buildConfigurations() {
const source = app.environmentSource;
const environments = app.environments;
const serviceWorker = app.serviceWorker;
const productionPartial = Object.assign({ optimization: true, outputHashing: 'all', sourceMap: false, extractCss: true, namedChunks: false, aot: true, extractLicenses: true, vendorChunk: false, buildOptimizer: true }, (serviceWorker ? { serviceWorker: true, ngswConfigPath: 'src/ngsw-config.json' } : {}), (app.budgets ? { budgets: app.budgets } : {}));
if (!environments) {
return { production: productionPartial };
}
const configurations = Object.keys(environments).reduce((acc, environment) => {
if (source === environments[environment]) {
return acc;
}
let isProduction = false;
const environmentContent = tree.read(app.root + '/' + environments[environment]);
if (environmentContent) {
isProduction = !!environmentContent.toString('utf-8')
// Allow for `production: true` or `production = true`. Best we can do to guess.
.match(/production['"]?\s*[:=]\s*true/);
}
let configurationName;
// We used to use `prod` by default as the key, instead we now use the full word.
// Try not to override the production key if it's there.
if (environment == 'prod' && !environments['production'] && isProduction) {
configurationName = 'production';
}
else {
configurationName = environment;
}
acc[configurationName] = Object.assign({}, (isProduction ? productionPartial : {}), { fileReplacements: [
{
replace: `${app.root}/${source}`,
with: `${app.root}/${environments[environment]}`,
},
] });
return acc;
}, {});
if (!configurations['production']) {
configurations['production'] = Object.assign({}, productionPartial);
}
return configurations;
}
function _serveConfigurations() {
const environments = app.environments;
if (!environments) {
return {};
}
if (!targets) {
throw new Error();
}
const configurations = targets.build.configurations;
return Object.keys(configurations).reduce((acc, environment) => {
acc[environment] = { browserTarget: `${name}:build:${environment}` };
return acc;
}, {});
}
function _extraEntryMapper(extraEntry) {
let entry;
if (typeof extraEntry === 'string') {
entry = core_1.join(app.root, extraEntry);
}
else {
const input = core_1.join(app.root, extraEntry.input || '');
entry = { input, lazy: extraEntry.lazy };
if (extraEntry.output) {
entry.bundleName = extraEntry.output;
}
}
return entry;
}
const projectRoot = core_1.join(core_1.normalize(appRoot), '..');
const project = {
root: projectRoot,
sourceRoot: appRoot,
projectType: 'application',
};
const targets = {};
project.architect = targets;
// Browser target
const buildOptions = Object.assign({
// Make outputPath relative to root.
outputPath: outDir, index: `${appRoot}/${app.index || defaults.index}`, main: `${appRoot}/${app.main || defaults.main}`, tsConfig: `${appRoot}/${app.tsconfig || defaults.tsConfig}` }, (app.baseHref ? { baseHref: app.baseHref } : {}), buildDefaults);
if (app.polyfills) {
buildOptions.polyfills = appRoot + '/' + app.polyfills;
}
if (app.stylePreprocessorOptions
&& app.stylePreprocessorOptions.includePaths
&& Array.isArray(app.stylePreprocessorOptions.includePaths)
&& app.stylePreprocessorOptions.includePaths.length > 0) {
buildOptions.stylePreprocessorOptions = {
includePaths: app.stylePreprocessorOptions.includePaths
.map(includePath => core_1.join(app.root, includePath)),
};
}
buildOptions.assets = (app.assets || []).map(_mapAssets).filter(x => !!x);
buildOptions.styles = (app.styles || []).map(_extraEntryMapper);
buildOptions.scripts = (app.scripts || []).map(_extraEntryMapper);
targets.build = {
builder: `${builderPackage}:browser`,
options: buildOptions,
configurations: _buildConfigurations(),
};
// Serve target
const serveOptions = Object.assign({ browserTarget: `${name}:build` }, serveDefaults);
targets.serve = {
builder: `${builderPackage}:dev-server`,
options: serveOptions,
configurations: _serveConfigurations(),
};
// Extract target
const extractI18nOptions = { browserTarget: `${name}:build` };
targets['extract-i18n'] = {
builder: `${builderPackage}:extract-i18n`,
options: extractI18nOptions,
};
const karmaConfig = config.test && config.test.karma
? config.test.karma.config || ''
: '';
// Test target
const testOptions = {
main: appRoot + '/' + app.test || defaults.test,
// Make karmaConfig relative to root.
karmaConfig,
};
if (app.polyfills) {
testOptions.polyfills = appRoot + '/' + app.polyfills;
}
if (app.testTsconfig) {
testOptions.tsConfig = appRoot + '/' + app.testTsconfig;
}
const codeCoverageExclude = config.test
&& config.test.codeCoverage
&& config.test.codeCoverage.exclude;
if (codeCoverageExclude) {
testOptions.codeCoverageExclude = codeCoverageExclude;
}
testOptions.scripts = (app.scripts || []).map(_extraEntryMapper);
testOptions.styles = (app.styles || []).map(_extraEntryMapper);
testOptions.assets = (app.assets || []).map(_mapAssets).filter(x => !!x);
if (karmaConfig) {
targets.test = {
builder: `${builderPackage}:karma`,
options: testOptions,
};
}
const tsConfigs = [];
const excludes = [];
let warnForLint = false;
if (config && config.lint && Array.isArray(config.lint)) {
config.lint.forEach(lint => {
if (lint.project) {
tsConfigs.push(lint.project);
}
else {
warnForLint = true;
}
if (lint.exclude) {
if (typeof lint.exclude === 'string') {
excludes.push(lint.exclude);
}
else {
lint.exclude.forEach(ex => excludes.push(ex));
}
}
});
}
if (warnForLint) {
logger.warn(`
Lint without 'project' was not migrated which is not supported in Angular CLI 6.
`);
}
const removeDupes = (items) => items.reduce((newItems, item) => {
if (newItems.indexOf(item) === -1) {
newItems.push(item);
}
return newItems;
}, []);
// Tslint target
const lintOptions = {
tsConfig: removeDupes(tsConfigs).filter(t => t.indexOf('e2e') === -1),
exclude: removeDupes(excludes),
};
targets.lint = {
builder: `${builderPackage}:tslint`,
options: lintOptions,
};
// server target
const serverApp = serverApps
.filter(serverApp => app.root === serverApp.root && app.index === serverApp.index)[0];
if (serverApp) {
const serverOptions = {
outputPath: serverApp.outDir || defaults.serverOutDir,
main: `${appRoot}/${serverApp.main || defaults.serverMain}`,
tsConfig: `${appRoot}/${serverApp.tsconfig || defaults.serverTsConfig}`,
};
const serverTarget = {
builder: '@angular-devkit/build-angular:server',
options: serverOptions,
};
targets.server = serverTarget;
}
const e2eProject = {
root: core_1.join(projectRoot, 'e2e'),
sourceRoot: core_1.join(projectRoot, 'e2e'),
projectType: 'application',
};
const e2eTargets = {};
// tslint:disable-next-line:max-line-length
const protractorConfig = config && config.e2e && config.e2e.protractor && config.e2e.protractor.config
? config.e2e.protractor.config
: '';
const e2eOptions = {
protractorConfig: protractorConfig,
devServerTarget: `${name}:serve`,
};
const e2eTarget = {
builder: `${builderPackage}:protractor`,
options: e2eOptions,
};
e2eTargets.e2e = e2eTarget;
const e2eLintOptions = {
tsConfig: removeDupes(tsConfigs).filter(t => t.indexOf('e2e') !== -1),
exclude: removeDupes(excludes),
};
const e2eLintTarget = {
builder: `${builderPackage}:tslint`,
options: e2eLintOptions,
};
e2eTargets.lint = e2eLintTarget;
if (protractorConfig) {
e2eProject.architect = e2eTargets;
}
return { name, project, e2eProject };
})
.reduce((projects, mappedApp) => {
const { name, project, e2eProject } = mappedApp;
projects[name] = project;
projects[name + '-e2e'] = e2eProject;
return projects;
}, {});
return projectMap;
}
function getDefaultAppNamePrefix(config) {
let defaultAppNamePrefix = 'app';
if (config.project && config.project.name) {
defaultAppNamePrefix = config.project.name;
}
return defaultAppNamePrefix;
}
function extractDefaultProject(config) {
if (config.apps && config.apps[0]) {
const app = config.apps[0];
const defaultAppName = getDefaultAppNamePrefix(config);
const name = app.name || defaultAppName;
return name;
}
return null;
}
function updateSpecTsConfig(config) {
return (host, context) => {
const apps = config.apps || [];
apps.forEach((app, idx) => {
const testTsConfig = app.testTsconfig || defaults.testTsConfig;
const tsSpecConfigPath = core_1.join(core_1.normalize(app.root || ''), testTsConfig);
const buffer = host.read(tsSpecConfigPath);
if (!buffer) {
return;
}
const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose);
if (tsCfgAst.kind != 'object') {
throw new schematics_1.SchematicsException('Invalid tsconfig. Was expecting an object');
}
const filesAstNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'files');
if (filesAstNode && filesAstNode.kind != 'array') {
throw new schematics_1.SchematicsException('Invalid tsconfig "files" property; expected an array.');
}
const recorder = host.beginUpdate(tsSpecConfigPath);
const polyfills = app.polyfills || defaults.polyfills;
if (!filesAstNode) {
// Do nothing if the files array does not exist. This means exclude or include are
// set and we shouldn't mess with that.
}
else {
if (filesAstNode.value.indexOf(polyfills) == -1) {
json_utils_1.appendValueInAstArray(recorder, filesAstNode, polyfills);
}
}
host.commitUpdate(recorder);
});
};
}
function updatePackageJson(config) {
return (host, context) => {
const dependency = {
type: dependencies_1.NodeDependencyType.Dev,
name: '@angular-devkit/build-angular',
version: latest_versions_1.latestVersions.DevkitBuildAngular,
overwrite: true,
};
dependencies_1.addPackageJsonDependency(host, dependency);
context.addTask(new tasks_1.NodePackageInstallTask({
packageManager: config.packageManager === 'default' ? undefined : config.packageManager,
}));
return host;
};
}
function updateTsLintConfig() {
return (host, context) => {
const tsLintPath = '/tslint.json';
const buffer = host.read(tsLintPath);
if (!buffer) {
return host;
}
const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose);
if (tsCfgAst.kind != 'object') {
return host;
}
const rulesNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'rules');
if (!rulesNode || rulesNode.kind != 'object') {
return host;
}
const importBlacklistNode = json_utils_1.findPropertyInAstObject(rulesNode, 'import-blacklist');
if (!importBlacklistNode || importBlacklistNode.kind != 'array') {
return host;
}
const recorder = host.beginUpdate(tsLintPath);
for (let i = 0; i < importBlacklistNode.elements.length; i++) {
const element = importBlacklistNode.elements[i];
if (element.kind == 'string' && element.value == 'rxjs') {
const { start, end } = element;
// Remove this element.
if (i == importBlacklistNode.elements.length - 1) {
// Last element.
if (i > 0) {
// Not first, there's a comma to remove before.
const previous = importBlacklistNode.elements[i - 1];
recorder.remove(previous.end.offset, end.offset - previous.end.offset);
}
else {
// Only element, just remove the whole rule.
const { start, end } = importBlacklistNode;
recorder.remove(start.offset, end.offset - start.offset);
recorder.insertLeft(start.offset, '[]');
}
}
else {
// Middle, just remove the whole node (up to next node start).
const next = importBlacklistNode.elements[i + 1];
recorder.remove(start.offset, next.start.offset - start.offset);
}
}
}
host.commitUpdate(recorder);
return host;
};
}
function updateRootTsConfig() {
return (host, context) => {
const tsConfigPath = '/tsconfig.json';
const buffer = host.read(tsConfigPath);
if (!buffer) {
return;
}
const tsCfgAst = core_1.parseJsonAst(buffer.toString(), core_1.JsonParseMode.Loose);
if (tsCfgAst.kind !== 'object') {
throw new schematics_1.SchematicsException('Invalid root tsconfig. Was expecting an object');
}
const compilerOptionsAstNode = json_utils_1.findPropertyInAstObject(tsCfgAst, 'compilerOptions');
if (!compilerOptionsAstNode || compilerOptionsAstNode.kind != 'object') {
throw new schematics_1.SchematicsException('Invalid root tsconfig "compilerOptions" property; expected an object.');
}
if (json_utils_1.findPropertyInAstObject(compilerOptionsAstNode, 'baseUrl') &&
json_utils_1.findPropertyInAstObject(compilerOptionsAstNode, 'module')) {
return host;
}
const compilerOptions = compilerOptionsAstNode.value;
const { baseUrl = './', module = 'es2015' } = compilerOptions;
const validBaseUrl = ['./', '', '.'];
if (!validBaseUrl.includes(baseUrl)) {
const formattedBaseUrl = validBaseUrl.map(x => `'${x}'`).join(', ');
context.logger.warn(core_1.tags.oneLine `Root tsconfig option 'baseUrl' is not one of: ${formattedBaseUrl}.
This might cause unexpected behaviour when generating libraries.`);
}
if (module !== 'es2015') {
context.logger.warn(`Root tsconfig option 'module' is not 'es2015'. This might cause unexpected behaviour.`);
}
compilerOptions.module = module;
compilerOptions.baseUrl = baseUrl;
host.overwrite(tsConfigPath, JSON.stringify(tsCfgAst.value, null, 2));
return host;
};
}
function default_1() {
return (host, context) => {
if (host.exists('/.angular.json') || host.exists('/angular.json')) {
context.logger.info('Found a modern configuration file. Nothing to be done.');
return host;
}
const configPath = getConfigPath(host);
const configBuffer = host.read(core_1.normalize(configPath));
if (configBuffer == null) {
throw new schematics_1.SchematicsException(`Could not find configuration file (${configPath})`);
}
const config = core_1.parseJson(configBuffer.toString(), core_1.JsonParseMode.Loose);
if (typeof config != 'object' || Array.isArray(config) || config === null) {
throw new schematics_1.SchematicsException('Invalid angular-cli.json configuration; expected an object.');
}
return schematics_1.chain([
migrateKarmaConfiguration(config),
migrateConfiguration(config, context.logger),
updateSpecTsConfig(config),
updatePackageJson(config),
updateRootTsConfig(),
updateTsLintConfig(),
(host, context) => {
context.logger.warn(core_1.tags.oneLine `Some configuration options have been changed,
please make sure to update any npm scripts which you may have modified.`);
return host;
},
]);
};
}
exports.default = default_1;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiLi8iLCJzb3VyY2VzIjpbInBhY2thZ2VzL3NjaGVtYXRpY3MvYW5ndWxhci9taWdyYXRpb25zL3VwZGF0ZS02L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7OztHQU1HO0FBQ0gsK0NBVzhCO0FBQzlCLDJEQU1vQztBQUNwQyw0REFBMEU7QUFFMUUsNkRBSW9DO0FBQ3BDLHlEQUdrQztBQUNsQyxtRUFBK0Q7QUFFL0QsTUFBTSxRQUFRLEdBQUc7SUFDZixPQUFPLEVBQUUsS0FBSztJQUNkLEtBQUssRUFBRSxZQUFZO0lBQ25CLElBQUksRUFBRSxTQUFTO0lBQ2YsU0FBUyxFQUFFLGNBQWM7SUFDekIsUUFBUSxFQUFFLG1CQUFtQjtJQUM3QixJQUFJLEVBQUUsU0FBUztJQUNmLE1BQU0sRUFBRSxPQUFPO0lBQ2YsS0FBSyxFQUFFLGVBQWU7SUFDdEIsVUFBVSxFQUFFLG9CQUFvQjtJQUNoQyxZQUFZLEVBQUUsb0JBQW9CO0lBQ2xDLFlBQVksRUFBRSxhQUFhO0lBQzNCLFVBQVUsRUFBRSxnQkFBZ0I7SUFDNUIsY0FBYyxFQUFFLHNCQUFzQjtDQUN2QyxDQUFDO0FBRUYsU0FBUyxhQUFhLENBQUMsSUFBVTtJQUMvQixJQUFJLFlBQVksR0FBRyxnQkFBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbEQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFO1FBQzdCLE9BQU8sWUFBWSxDQUFDO0tBQ3JCO0lBQ0QsWUFBWSxHQUFHLGdCQUFTLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM3QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUU7UUFDN0IsT0FBTyxZQUFZLENBQUM7S0FDckI7SUFFRCxNQUFNLElBQUksZ0NBQW1CLENBQUMsbUNBQW1DLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxNQUFpQjtJQUNsRCxPQUFPLENBQUMsSUFBVSxFQUFFLE9BQXlCLEVBQUUsRUFBRTtRQUMvQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBQ3BELElBQUk7WUFDRixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO2dCQUN0RixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFDMUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDbkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNwQyxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUU7Z0JBQ25CLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDaEMscUZBQXFGO2dCQUNyRiwwREFBMEQ7Z0JBQzFELE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLCtDQUErQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyw4Q0FBOEMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDOUUsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0NBQW9DLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3BFLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLG1DQUFtQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDcEQsNEJBQTRCO2dCQUM1QixPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO2dCQUM3RSxxQ0FBcUM7Z0JBQ3JDLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFDakMsMkRBQTJELENBQUMsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDcEM7U0FDRjtRQUFDLFdBQU0sR0FBRztRQUVYLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQUMsU0FBb0IsRUFBRSxNQUF5QjtJQUMzRSxPQUFPLENBQUMsSUFBVSxFQUFFLE9BQXlCLEVBQUUsRUFBRTtRQUMvQyxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsZ0JBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM3QyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sTUFBTSxHQUFlO1lBQ3pCLFNBQVMsRUFBRSxvREFBb0Q7WUFDL0QsT0FBTyxFQUFFLENBQUM7WUFDVixjQUFjLEVBQUUsVUFBVTtZQUMxQixRQUFRLEVBQUUscUJBQXFCLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUM7U0FDekQsQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELElBQUksY0FBYyxLQUFLLElBQUksRUFBRTtZQUMzQixNQUFNLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztTQUN4QztRQUNELE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLElBQUksU0FBUyxLQUFLLElBQUksRUFBRTtZQUN0QixNQUFNLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQztTQUN4QjtRQUNELE1BQU0sZ0JBQWdCLEdBQUcsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUQsSUFBSSxnQkFBZ0IsS0FBSyxJQUFJLEVBQUU7WUFDN0IsTUFBTSxDQUFDLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQztTQUN0QztRQUNELE1BQU0sYUFBYSxHQUFHLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3RELElBQUksYUFBYSxLQUFLLElBQUksRUFBRTtZQUMxQixNQUFNLENBQUMsU0FBUyxHQUFHLGFBQWEsQ0FBQztTQUNsQztRQUVELE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0IsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFpQjtJQUN6QyxNQUFNLFNBQVMsR0FBZSxFQUFFLENBQUM7SUFDakMsSUFBSSxNQUFNLENBQUMsY0FBYyxJQUFJLE1BQU0sQ0FBQyxjQUFjLEtBQUssU0FBUyxFQUFFO1FBQ2hFLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUM7S0FDckQ7SUFDRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUU7UUFDbkIsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUU7WUFDakQsU0FBUyxDQUFDLFFBQVEscUJBQ2IsQ0FBRSxTQUFTLENBQUMsUUFBOEIsSUFBSSxFQUFFLENBQUMsRUFDakQsRUFBRSxlQUFlLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsQ0FDeEQsQ0FBQztTQUNIO1FBQ0QsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRTtZQUNwRCxTQUFTLENBQUMsUUFBUSxxQkFDYixDQUFFLFNBQVMsQ0FBQyxRQUE4QixJQUFJLEVBQUUsQ0FBQyxFQUNqRCxFQUFFLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsQ0FDOUQsQ0FBQztTQUNIO0tBQ0Y7SUFFRCxPQUFPLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM5RSxDQUFDO0FBRUQsU0FBUyx1QkFBdUIsQ0FBQyxNQUFpQjtJQUNoRCxJQUFJLGNBQWMsR0FBRyxxQkFBcUIsQ0FBQztJQUMzQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUMvQixPQUFPLElBQUksQ0FBQztLQUNiO0lBQ0QsMENBQTBDO0lBQzFDLElBQUksTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUU7UUFDMUYsY0FBYyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztLQUN4RDtJQUVEOzs7OztPQUtHO0lBQ0gsa0NBQWtDO0lBQ2xDLE1BQU0sZ0JBQWdCLEdBQVEsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPO1FBQzFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQztTQUNyRSxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUU7UUFDbkIsa0NBQWtDO1FBQ2xDLE1BQU0saUJBQWlCLEdBQWdCLE1BQU0sQ0FBQyxRQUFnQixDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksQ0FBQztRQUV0RixPQUFPO1lBQ0wsYUFBYTtZQUNiLE1BQU0sRUFBRSxpQkFBaUI7U0FDMUIsQ0FBQztJQUNKLENBQUMsQ0FBQztTQUNELE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDO1NBQzlDLE1BQU0sQ0FBQyxDQUFDLEdBQWUsRUFBRSxTQUFTLEVBQUUsRUFBRTtRQUNyQyxHQUFHLENBQUMsY0FBYyxHQUFHLEdBQUcsR0FBRyxTQUFTLENBQUMsYUFBYSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUV2RSxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUVULE1BQU0sZUFBZSxHQUFlLEVBQUUsQ0FBQztJQUN2QyxlQUFlLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUU1QixNQUFNLFlBQVksR0FBRyxjQUFjLEdBQUcsWUFBWSxDQUFDO0lBQ25ELE1BQU0sWUFBWSxHQUFHLGNBQWMsR0FBRyxZQUFZLENBQUM7SUFDbkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxFQUFFO1FBQ25DLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNyQztJQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsRUFBRTtRQUNuQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDckM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUNqQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDOUQsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0tBQy9EO0lBQ0QsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFO1FBQ25CLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztLQUNwRTtJQUVELE9BQU8sZ0JBQWdCLENBQUM7QUFDMUIsQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQUMsT0FBa0I7SUFDOUMsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsMEZBQTBGO0FBQzFGLHNDQUFzQztBQUN0QywyQ0FBMkM7QUFDM0MsU0FBUyxxQkFBcUIsQ0FDNUIsTUFBaUIsRUFBRSxJQUFVLEVBQUUsTUFBeUI7SUFFeEQsTUFBTSxjQUFjLEdBQUcsK0JBQStCLENBQUM7SUFDdkQsTUFBTSxvQkFBb0IsR0FBRyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUU3RCxNQUFNLGFBQWEsR0FBZSxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSztRQUN4RSxDQUFDLENBQUM7WUFDQSxTQUFTLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsVUFBVTtZQUMzQyxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUTtZQUN4QyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUNoQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0I7WUFDeEQsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCO1lBQ3hELHdCQUF3QixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLHdCQUF3QjtZQUN4RSxXQUFXLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVztZQUM5QyxXQUFXLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVztTQUNqQztRQUNmLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFUCxNQUFNLGFBQWEsR0FBZSxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSztRQUN4RSxDQUFDLENBQUM7WUFDQSxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUNoQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUNoQyxHQUFHLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRztZQUM5QixNQUFNLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTTtZQUNwQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTztZQUN0QyxXQUFXLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVztTQUNqQztRQUNmLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFHUCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUMvQiwrQkFBK0I7SUFDL0IsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUM7SUFDbEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUM7SUFFakUsTUFBTSxVQUFVLEdBQUcsV0FBVztRQUM1QiwwRkFBMEY7UUFDMUYsc0NBQXNDO1FBQ3RDLDJDQUEyQztTQUMxQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7UUFDaEIsTUFBTSxjQUFjLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEdBQUcsb0JBQW9CLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDMUYsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxjQUFjLENBQUM7UUFDeEMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQzdDLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUU3QyxTQUFTLFVBQVUsQ0FBQyxLQUEwQjtZQUM1QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtnQkFDN0IsT0FBTyxnQkFBUyxDQUFDLE9BQU8sR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUM7YUFDekM7aUJBQU07Z0JBQ0wsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEVBQUU7b0JBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBSSxDQUFDLE9BQU8sQ0FBQTtrQ0FDRixLQUFLLENBQUMsS0FBSzs7YUFFaEMsQ0FBQyxDQUFDO29CQUVILE9BQU8sSUFBSSxDQUFDO2lCQUNiO3FCQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtvQkFDdkIsT0FBTzt3QkFDTCxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7d0JBQ2hCLEtBQUssRUFBRSxnQkFBUyxDQUFDLE9BQU8sR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQzt3QkFDN0MsTUFBTSxFQUFFLGdCQUFTLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFnQixDQUFDO3FCQUNoRCxDQUFDO2lCQUNIO3FCQUFNO29CQUNMLE9BQU87d0JBQ0wsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO3dCQUNoQixLQUFLLEVBQUUsZ0JBQVMsQ0FBQyxPQUFPLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7d0JBQzdDLE1BQU0sRUFBRSxHQUFHO3FCQUNaLENBQUM7aUJBQ0g7YUFDRjtRQUNILENBQUM7UUFFRCxTQUFTLG9CQUFvQjtZQUMzQixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsaUJBQWlCLENBQUM7WUFDckMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQztZQUN0QyxNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDO1lBRXhDLE1BQU0saUJBQWlCLG1CQUNyQixZQUFZLEVBQUUsSUFBSSxFQUNsQixhQUFhLEVBQUUsS0FBSyxFQUNwQixTQUFTLEVBQUUsS0FBSyxFQUNoQixVQUFVLEVBQUUsSUFBSSxFQUNoQixXQUFXLEVBQUUsS0FBSyxFQUNsQixHQUFHLEVBQUUsSUFBSSxFQUNULGVBQWUsRUFBRSxJQUFJLEVBQ3JCLFdBQVcsRUFBRSxLQUFLLEVBQ2xCLGNBQWMsRUFBRSxJQUFJLElBQ2pCLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLHNCQUFzQixFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUNwRixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFvQixFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUM3RCxDQUFDO1lBRUYsSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDakIsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDO2FBQzFDO1lBRUQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLEVBQUU7Z0JBQzNFLElBQUksTUFBTSxLQUFLLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRTtvQkFDeEMsT0FBTyxHQUFHLENBQUM7aUJBQ1o7Z0JBRUQsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO2dCQUV6QixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pGLElBQUksa0JBQWtCLEVBQUU7b0JBQ3RCLFlBQVksR0FBRyxDQUFDLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQzt3QkFDbkQsZ0ZBQWdGO3lCQUMvRSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztpQkFDM0M7Z0JBRUQsSUFBSSxpQkFBaUIsQ0FBQztnQkFDdEIsaUZBQWlGO2dCQUNqRix3REFBd0Q7Z0JBQ3hELElBQUksV0FBVyxJQUFJLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsSUFBSSxZQUFZLEVBQUU7b0JBQ3hFLGlCQUFpQixHQUFHLFlBQVksQ0FBQztpQkFDbEM7cUJBQU07b0JBQ0wsaUJBQWlCLEdBQUcsV0FBVyxDQUFDO2lCQUNqQztnQkFFRCxHQUFHLENBQUMsaUJBQWlCLENBQUMscUJBQ2pCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQzFDLGdCQUFnQixFQUFFO3dCQUNoQjs0QkFDRSxPQUFPLEVBQUUsR0FBRyxHQUFHLENBQUMsSUFBSSxJQUFJLE1BQU0sRUFBRTs0QkFDaEMsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUU7eUJBQ2pEO3FCQUNGLEdBQ0YsQ0FBQztnQkFFRixPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUMsRUFBRSxFQUFnQixDQUFDLENBQUM7WUFFckIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDakMsY0FBYyxDQUFDLFlBQVksQ0FBQyxxQkFBUSxpQkFBaUIsQ0FBRSxDQUFDO2FBQ3pEO1lBRUQsT0FBTyxjQUFjLENBQUM7UUFDeEIsQ0FBQztRQUVELFNBQVMsb0JBQW9CO1lBQzNCLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUM7WUFFdEMsSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDakIsT0FBTyxFQUFFLENBQUM7YUFDWDtZQUNELElBQUksQ0FBQyxPQUFPLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO2FBQ25CO1lBRUQsTUFBTSxjQUFjLEdBQUksT0FBTyxDQUFDLEtBQW9CLENBQUMsY0FBNEIsQ0FBQztZQUVsRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxFQUFFO2dCQUM3RCxHQUFHLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsR0FBRyxJQUFJLFVBQVUsV0FBVyxFQUFFLEVBQUUsQ0FBQztnQkFFckUsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQUUsRUFBZ0IsQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFFRCxTQUFTLGlCQUFpQixDQUFDLFVBQStCO1lBQ3hELElBQUksS0FBMEIsQ0FBQztZQUMvQixJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsS0FBSyxHQUFHLFdBQUksQ0FBQyxHQUFHLENBQUMsSUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQzVDO2lCQUFNO2dCQUNMLE1BQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxHQUFHLENBQUMsSUFBWSxFQUFFLFVBQVUsQ0FBQyxLQUFlLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3ZFLEtBQUssR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUV6QyxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUU7b0JBQ3JCLEtBQUssQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztpQkFDdEM7YUFDRjtZQUVELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLFdBQUksQ0FBQyxnQkFBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ25ELE1BQU0sT0FBTyxHQUFlO1lBQzFCLElBQUksRUFBRSxXQUFXO1lBQ2pCLFVBQVUsRUFBRSxPQUFPO1lBQ25CLFdBQVcsRUFBRSxhQUFhO1NBQzNCLENBQUM7UUFFRixNQUFNLE9BQU8sR0FBZSxFQUFFLENBQUM7UUFDL0IsT0FBTyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUM7UUFFMUIsaUJBQWlCO1FBQ25CLE1BQU0sWUFBWTtZQUNoQixvQ0FBb0M7WUFDcEMsVUFBVSxFQUFFLE1BQU0sRUFDbEIsS0FBSyxFQUFFLEdBQUcsT0FBTyxJQUFJLEdBQUcsQ0FBQyxLQUFLLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxFQUNsRCxJQUFJLEVBQUUsR0FBRyxPQUFPLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQy9DLFFBQVEsRUFBRSxHQUFHLE9BQU8sSUFBSSxHQUFHLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUUsSUFDeEQsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUNoRCxhQUFhLENBQ2pCLENBQUM7UUFFRixJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQUU7WUFDakIsWUFBWSxDQUFDLFNBQVMsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7U0FDeEQ7UUFFRCxJQUFJLEdBQUcsQ0FBQyx3QkFBd0I7ZUFDekIsR0FBRyxDQUFDLHdCQUF3QixDQUFDLFlBQVk7ZUFDekMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsWUFBWSxDQUFDO2VBQ3hELEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzRCxZQUFZLENBQUMsd0JBQXdCLEdBQUc7Z0JBQ3RDLFlBQVksRUFBRSxHQUFHLENBQUMsd0JBQXdCLENBQUMsWUFBWTtxQkFDcEQsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsV0FBSSxDQUFDLEdBQUcsQ0FBQyxJQUFZLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDM0QsQ0FBQztTQUNIO1FBRUQsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxRSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNoRSxZQUFZLENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRSxPQUFPLENBQUMsS0FBSyxHQUFHO1lBQ2QsT0FBTyxFQUFFLEdBQUcsY0FBYyxVQUFVO1lBQ3BDLE9BQU8sRUFBRSxZQUFZO1lBQ3JCLGNBQWMsRUFBRSxvQkFBb0IsRUFBRTtTQUN2QyxDQUFDO1FBRUYsZUFBZTtRQUNmLE1BQU0sWUFBWSxtQkFDaEIsYUFBYSxFQUFFLEdBQUcsSUFBSSxRQUFRLElBQzNCLGFBQWEsQ0FDakIsQ0FBQztRQUNGLE9BQU8sQ0FBQyxLQUFLLEdBQUc7WUFDZCxPQUFPLEVBQUUsR0FBRyxjQUFjLGFBQWE7WUFDdkMsT0FBTyxFQUFFLFlBQVk7WUFDckIsY0FBYyxFQUFFLG9CQUFvQixFQUFFO1NBQ3ZDLENBQUM7UUFFRixpQkFBaUI7UUFDakIsTUFBTSxrQkFBa0IsR0FBZSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7UUFDMUUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHO1lBQ3hCLE9BQU8sRUFBRSxHQUFHLGNBQWMsZUFBZTtZQUN6QyxPQUFPLEVBQUUsa0JBQWtCO1NBQzVCLENBQUM7UUFFRixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSztZQUNoRCxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxJQUFJLEVBQUU7WUFDaEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNQLGNBQWM7UUFDaEIsTUFBTSxXQUFXLEdBQWU7WUFDNUIsSUFBSSxFQUFFLE9BQU8sR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsSUFBSTtZQUMvQyxxQ0FBcUM7WUFDckMsV0FBVztTQUNaLENBQUM7UUFFSixJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQUU7WUFDakIsV0FBVyxDQUFDLFNBQVMsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7U0FDdkQ7UUFFRCxJQUFJLEdBQUcsQ0FBQyxZQUFZLEVBQUU7WUFDbEIsV0FBVyxDQUFDLFFBQVEsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUM7U0FDM0Q7UUFFRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxJQUFJO2VBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWTtlQUN4QixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUM7UUFFdEMsSUFBSSxtQkFBbUIsRUFBRTtZQUN2QixXQUFXLENBQUMsbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7U0FDdkQ7UUFFRCxXQUFXLENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNqRSxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUMvRCxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpFLElBQUksV0FBVyxFQUFFO1lBQ2YsT0FBTyxDQUFDLElBQUksR0FBRztnQkFDYixPQUFPLEVBQUUsR0FBRyxjQUFjLFFBQVE7Z0JBQ2xDLE9BQU8sRUFBRSxXQUFXO2FBQ3JCLENBQUM7U0FDSDtRQUVELE1BQU0sU0FBUyxHQUFhLEVBQUUsQ0FBQztRQUMvQixNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3pCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDaEIsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQzlCO3FCQUFNO29CQUNMLFdBQVcsR0FBRyxJQUFJLENBQUM7aUJBQ3BCO2dCQUVELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDaEIsSUFBSSxPQUFPLElBQUksQ0FBQyxPQUFPLEtBQUssUUFBUSxFQUFFO3dCQUNwQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDN0I7eUJBQU07d0JBQ0wsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7cUJBQy9DO2lCQUNGO1lBQ0gsQ0FBQyxDQUFDLENBQUM7U0FDSjtRQUVELElBQUksV0FBVyxFQUFFO1lBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQzs7U0FFWCxDQUFDLENBQUM7U0FDSjtRQUVELE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3ZFLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtnQkFDakMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNyQjtZQUVELE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUMsRUFBRSxFQUFjLENBQUMsQ0FBQztRQUVqQixnQkFBZ0I7UUFDbEIsTUFBTSxXQUFXLEdBQWU7WUFDOUIsUUFBUSxFQUFFLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ3JFLE9BQU8sRUFBRSxXQUFXLENBQUMsUUFBUSxDQUFDO1NBQy9CLENBQUM7UUFDRixPQUFPLENBQUMsSUFBSSxHQUFHO1lBQ1gsT0FBTyxFQUFFLEdBQUcsY0FBYyxTQUFTO1lBQ25DLE9BQU8sRUFBRSxXQUFXO1NBQ3JCLENBQUM7UUFFSixnQkFBZ0I7UUFDaEIsTUFBTSxTQUFTLEdBQUcsVUFBVTthQUN6QixNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFeEYsSUFBSSxTQUFTLEVBQUU7WUFDYixNQUFNLGFBQWEsR0FBZTtnQkFDaEMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLFlBQVk7Z0JBQ3JELElBQUksRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUU7Z0JBQzNELFFBQVEsRUFBRSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUU7YUFDeEUsQ0FBQztZQUNGLE1BQU0sWUFBWSxHQUFlO2dCQUMvQixPQUFPLEVBQUUsc0NBQXNDO2dCQUMvQyxPQUFPLEVBQUUsYUFBYTthQUN2QixDQUFDO1lBQ0YsT0FBTyxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUM7U0FDL0I7UUFDRCxNQUFNLFVBQVUsR0FBZTtZQUM3QixJQUFJLEVBQUUsV0FBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUM7WUFDOUIsVUFBVSxFQUFFLFdBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDO1lBQ3BDLFdBQVcsRUFBRSxhQUFhO1NBQzNCLENBQUM7UUFFRixNQUFNLFVBQVUsR0FBZSxFQUFFLENBQUM7UUFFbEMsMkNBQTJDO1FBQzNDLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTTtZQUNwRyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTTtZQUM5QixDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1AsTUFBTSxVQUFVLEdBQWU7WUFDN0IsZ0JBQWdCLEVBQUUsZ0JBQWdCO1lBQ2xDLGVBQWUsRUFBRSxHQUFHLElBQUksUUFBUTtTQUNqQyxDQUFDO1FBQ0YsTUFBTSxTQUFTLEdBQWU7WUFDNUIsT0FBTyxFQUFFLEdBQUcsY0FBYyxhQUFhO1lBQ3ZDLE9BQU8sRUFBRSxVQUFVO1NBQ3BCLENBQUM7UUFFRixVQUFVLENBQUMsR0FBRyxHQUFHLFNBQ