UNPKG

lightfold

Version:

lightweight scaffolding and archiving utility CLI.

893 lines (771 loc) 93.3 kB
'use strict'; var _ExportMap = require('../ExportMap'); var _ExportMap2 = _interopRequireDefault(_ExportMap); var _ignore = require('eslint-module-utils/ignore'); var _resolve = require('eslint-module-utils/resolve'); var _resolve2 = _interopRequireDefault(_resolve); var _docsUrl = require('../docsUrl'); var _docsUrl2 = _interopRequireDefault(_docsUrl); var _path = require('path'); var _readPkgUp = require('read-pkg-up'); var _readPkgUp2 = _interopRequireDefault(_readPkgUp); var _object = require('object.values'); var _object2 = _interopRequireDefault(_object); var _arrayIncludes = require('array-includes'); var _arrayIncludes2 = _interopRequireDefault(_arrayIncludes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } /** * @fileOverview Ensures that modules contain exports and/or all * modules are consumed within other modules. * @author René Fermann */ // eslint/lib/util/glob-util has been moved to eslint/lib/util/glob-utils with version 5.3 // and has been moved to eslint/lib/cli-engine/file-enumerator in version 6 let listFilesToProcess; try { const FileEnumerator = require('eslint/lib/cli-engine/file-enumerator').FileEnumerator; listFilesToProcess = function (src, extensions) { const e = new FileEnumerator({ extensions: extensions }); return Array.from(e.iterateFiles(src), (_ref) => { let filePath = _ref.filePath, ignored = _ref.ignored; return { ignored, filename: filePath }; }); }; } catch (e1) { // Prevent passing invalid options (extensions array) to old versions of the function. // https://github.com/eslint/eslint/blob/v5.16.0/lib/util/glob-utils.js#L178-L280 // https://github.com/eslint/eslint/blob/v5.2.0/lib/util/glob-util.js#L174-L269 let originalListFilesToProcess; try { originalListFilesToProcess = require('eslint/lib/util/glob-utils').listFilesToProcess; listFilesToProcess = function (src, extensions) { return originalListFilesToProcess(src, { extensions: extensions }); }; } catch (e2) { originalListFilesToProcess = require('eslint/lib/util/glob-util').listFilesToProcess; listFilesToProcess = function (src, extensions) { const patterns = src.reduce((carry, pattern) => { return carry.concat(extensions.map(extension => { return (/\*\*|\*\./.test(pattern) ? pattern : `${pattern}/**/*${extension}` ); })); }, src.slice()); return originalListFilesToProcess(patterns); }; } } const EXPORT_DEFAULT_DECLARATION = 'ExportDefaultDeclaration'; const EXPORT_NAMED_DECLARATION = 'ExportNamedDeclaration'; const EXPORT_ALL_DECLARATION = 'ExportAllDeclaration'; const IMPORT_DECLARATION = 'ImportDeclaration'; const IMPORT_NAMESPACE_SPECIFIER = 'ImportNamespaceSpecifier'; const IMPORT_DEFAULT_SPECIFIER = 'ImportDefaultSpecifier'; const VARIABLE_DECLARATION = 'VariableDeclaration'; const FUNCTION_DECLARATION = 'FunctionDeclaration'; const CLASS_DECLARATION = 'ClassDeclaration'; const DEFAULT = 'default'; const TYPE_ALIAS = 'TypeAlias'; const importList = new Map(); const exportList = new Map(); const ignoredFiles = new Set(); const filesOutsideSrc = new Set(); const isNodeModule = path => { return (/\/(node_modules)\//.test(path) ); }; /** * read all files matching the patterns in src and ignoreExports * * return all files matching src pattern, which are not matching the ignoreExports pattern */ const resolveFiles = (src, ignoreExports, context) => { const extensions = Array.from((0, _ignore.getFileExtensions)(context.settings)); const srcFiles = new Set(); const srcFileList = listFilesToProcess(src, extensions); // prepare list of ignored files const ignoredFilesList = listFilesToProcess(ignoreExports, extensions); ignoredFilesList.forEach((_ref2) => { let filename = _ref2.filename; return ignoredFiles.add(filename); }); // prepare list of source files, don't consider files from node_modules srcFileList.filter((_ref3) => { let filename = _ref3.filename; return !isNodeModule(filename); }).forEach((_ref4) => { let filename = _ref4.filename; srcFiles.add(filename); }); return srcFiles; }; /** * parse all source files and build up 2 maps containing the existing imports and exports */ const prepareImportsAndExports = (srcFiles, context) => { const exportAll = new Map(); srcFiles.forEach(file => { const exports = new Map(); const imports = new Map(); const currentExports = _ExportMap2.default.get(file, context); if (currentExports) { const dependencies = currentExports.dependencies, reexports = currentExports.reexports, localImportList = currentExports.imports, namespace = currentExports.namespace; // dependencies === export * from const currentExportAll = new Set(); dependencies.forEach(getDependency => { const dependency = getDependency(); if (dependency === null) { return; } currentExportAll.add(dependency.path); }); exportAll.set(file, currentExportAll); reexports.forEach((value, key) => { if (key === DEFAULT) { exports.set(IMPORT_DEFAULT_SPECIFIER, { whereUsed: new Set() }); } else { exports.set(key, { whereUsed: new Set() }); } const reexport = value.getImport(); if (!reexport) { return; } let localImport = imports.get(reexport.path); let currentValue; if (value.local === DEFAULT) { currentValue = IMPORT_DEFAULT_SPECIFIER; } else { currentValue = value.local; } if (typeof localImport !== 'undefined') { localImport = new Set([].concat(_toConsumableArray(localImport), [currentValue])); } else { localImport = new Set([currentValue]); } imports.set(reexport.path, localImport); }); localImportList.forEach((value, key) => { if (isNodeModule(key)) { return; } imports.set(key, value.importedSpecifiers); }); importList.set(file, imports); // build up export list only, if file is not ignored if (ignoredFiles.has(file)) { return; } namespace.forEach((value, key) => { if (key === DEFAULT) { exports.set(IMPORT_DEFAULT_SPECIFIER, { whereUsed: new Set() }); } else { exports.set(key, { whereUsed: new Set() }); } }); } exports.set(EXPORT_ALL_DECLARATION, { whereUsed: new Set() }); exports.set(IMPORT_NAMESPACE_SPECIFIER, { whereUsed: new Set() }); exportList.set(file, exports); }); exportAll.forEach((value, key) => { value.forEach(val => { const currentExports = exportList.get(val); const currentExport = currentExports.get(EXPORT_ALL_DECLARATION); currentExport.whereUsed.add(key); }); }); }; /** * traverse through all imports and add the respective path to the whereUsed-list * of the corresponding export */ const determineUsage = () => { importList.forEach((listValue, listKey) => { listValue.forEach((value, key) => { const exports = exportList.get(key); if (typeof exports !== 'undefined') { value.forEach(currentImport => { let specifier; if (currentImport === IMPORT_NAMESPACE_SPECIFIER) { specifier = IMPORT_NAMESPACE_SPECIFIER; } else if (currentImport === IMPORT_DEFAULT_SPECIFIER) { specifier = IMPORT_DEFAULT_SPECIFIER; } else { specifier = currentImport; } if (typeof specifier !== 'undefined') { const exportStatement = exports.get(specifier); if (typeof exportStatement !== 'undefined') { const whereUsed = exportStatement.whereUsed; whereUsed.add(listKey); exports.set(specifier, { whereUsed }); } } }); } }); }); }; const getSrc = src => { if (src) { return src; } return [process.cwd()]; }; /** * prepare the lists of existing imports and exports - should only be executed once at * the start of a new eslint run */ let srcFiles; let lastPrepareKey; const doPreparation = (src, ignoreExports, context) => { const prepareKey = JSON.stringify({ src: (src || []).sort(), ignoreExports: (ignoreExports || []).sort(), extensions: Array.from((0, _ignore.getFileExtensions)(context.settings)).sort() }); if (prepareKey === lastPrepareKey) { return; } importList.clear(); exportList.clear(); ignoredFiles.clear(); filesOutsideSrc.clear(); srcFiles = resolveFiles(getSrc(src), ignoreExports, context); prepareImportsAndExports(srcFiles, context); determineUsage(); lastPrepareKey = prepareKey; }; const newNamespaceImportExists = specifiers => specifiers.some((_ref5) => { let type = _ref5.type; return type === IMPORT_NAMESPACE_SPECIFIER; }); const newDefaultImportExists = specifiers => specifiers.some((_ref6) => { let type = _ref6.type; return type === IMPORT_DEFAULT_SPECIFIER; }); const fileIsInPkg = file => { var _readPkgUp$sync = _readPkgUp2.default.sync({ cwd: file, normalize: false }); const path = _readPkgUp$sync.path, pkg = _readPkgUp$sync.pkg; const basePath = (0, _path.dirname)(path); const checkPkgFieldString = pkgField => { if ((0, _path.join)(basePath, pkgField) === file) { return true; } }; const checkPkgFieldObject = pkgField => { const pkgFieldFiles = (0, _object2.default)(pkgField).map(value => (0, _path.join)(basePath, value)); if ((0, _arrayIncludes2.default)(pkgFieldFiles, file)) { return true; } }; const checkPkgField = pkgField => { if (typeof pkgField === 'string') { return checkPkgFieldString(pkgField); } if (typeof pkgField === 'object') { return checkPkgFieldObject(pkgField); } }; if (pkg.private === true) { return false; } if (pkg.bin) { if (checkPkgField(pkg.bin)) { return true; } } if (pkg.browser) { if (checkPkgField(pkg.browser)) { return true; } } if (pkg.main) { if (checkPkgFieldString(pkg.main)) { return true; } } return false; }; module.exports = { meta: { type: 'suggestion', docs: { url: (0, _docsUrl2.default)('no-unused-modules') }, schema: [{ properties: { src: { description: 'files/paths to be analyzed (only for unused exports)', type: 'array', minItems: 1, items: { type: 'string', minLength: 1 } }, ignoreExports: { description: 'files/paths for which unused exports will not be reported (e.g module entry points)', type: 'array', minItems: 1, items: { type: 'string', minLength: 1 } }, missingExports: { description: 'report modules without any exports', type: 'boolean' }, unusedExports: { description: 'report exports without any usage', type: 'boolean' } }, not: { properties: { unusedExports: { enum: [false] }, missingExports: { enum: [false] } } }, anyOf: [{ not: { properties: { unusedExports: { enum: [true] } } }, required: ['missingExports'] }, { not: { properties: { missingExports: { enum: [true] } } }, required: ['unusedExports'] }, { properties: { unusedExports: { enum: [true] } }, required: ['unusedExports'] }, { properties: { missingExports: { enum: [true] } }, required: ['missingExports'] }] }] }, create: context => { var _ref7 = context.options[0] || {}; const src = _ref7.src; var _ref7$ignoreExports = _ref7.ignoreExports; const ignoreExports = _ref7$ignoreExports === undefined ? [] : _ref7$ignoreExports, missingExports = _ref7.missingExports, unusedExports = _ref7.unusedExports; if (unusedExports) { doPreparation(src, ignoreExports, context); } const file = context.getFilename(); const checkExportPresence = node => { if (!missingExports) { return; } if (ignoredFiles.has(file)) { return; } const exportCount = exportList.get(file); const exportAll = exportCount.get(EXPORT_ALL_DECLARATION); const namespaceImports = exportCount.get(IMPORT_NAMESPACE_SPECIFIER); exportCount.delete(EXPORT_ALL_DECLARATION); exportCount.delete(IMPORT_NAMESPACE_SPECIFIER); if (exportCount.size < 1) { // node.body[0] === 'undefined' only happens, if everything is commented out in the file // being linted context.report(node.body[0] ? node.body[0] : node, 'No exports found'); } exportCount.set(EXPORT_ALL_DECLARATION, exportAll); exportCount.set(IMPORT_NAMESPACE_SPECIFIER, namespaceImports); }; const checkUsage = (node, exportedValue) => { if (!unusedExports) { return; } if (ignoredFiles.has(file)) { return; } if (fileIsInPkg(file)) { return; } if (filesOutsideSrc.has(file)) { return; } // make sure file to be linted is included in source files if (!srcFiles.has(file)) { srcFiles = resolveFiles(getSrc(src), ignoreExports, context); if (!srcFiles.has(file)) { filesOutsideSrc.add(file); return; } } exports = exportList.get(file); // special case: export * from const exportAll = exports.get(EXPORT_ALL_DECLARATION); if (typeof exportAll !== 'undefined' && exportedValue !== IMPORT_DEFAULT_SPECIFIER) { if (exportAll.whereUsed.size > 0) { return; } } // special case: namespace import const namespaceImports = exports.get(IMPORT_NAMESPACE_SPECIFIER); if (typeof namespaceImports !== 'undefined') { if (namespaceImports.whereUsed.size > 0) { return; } } const exportStatement = exports.get(exportedValue); const value = exportedValue === IMPORT_DEFAULT_SPECIFIER ? DEFAULT : exportedValue; if (typeof exportStatement !== 'undefined') { if (exportStatement.whereUsed.size < 1) { context.report(node, `exported declaration '${value}' not used within other modules`); } } else { context.report(node, `exported declaration '${value}' not used within other modules`); } }; /** * only useful for tools like vscode-eslint * * update lists of existing exports during runtime */ const updateExportUsage = node => { if (ignoredFiles.has(file)) { return; } let exports = exportList.get(file); // new module has been created during runtime // include it in further processing if (typeof exports === 'undefined') { exports = new Map(); } const newExports = new Map(); const newExportIdentifiers = new Set(); node.body.forEach((_ref8) => { let type = _ref8.type, declaration = _ref8.declaration, specifiers = _ref8.specifiers; if (type === EXPORT_DEFAULT_DECLARATION) { newExportIdentifiers.add(IMPORT_DEFAULT_SPECIFIER); } if (type === EXPORT_NAMED_DECLARATION) { if (specifiers.length > 0) { specifiers.forEach(specifier => { if (specifier.exported) { newExportIdentifiers.add(specifier.exported.name); } }); } if (declaration) { if (declaration.type === FUNCTION_DECLARATION || declaration.type === CLASS_DECLARATION || declaration.type === TYPE_ALIAS) { newExportIdentifiers.add(declaration.id.name); } if (declaration.type === VARIABLE_DECLARATION) { declaration.declarations.forEach((_ref9) => { let id = _ref9.id; newExportIdentifiers.add(id.name); }); } } } }); // old exports exist within list of new exports identifiers: add to map of new exports exports.forEach((value, key) => { if (newExportIdentifiers.has(key)) { newExports.set(key, value); } }); // new export identifiers added: add to map of new exports newExportIdentifiers.forEach(key => { if (!exports.has(key)) { newExports.set(key, { whereUsed: new Set() }); } }); // preserve information about namespace imports let exportAll = exports.get(EXPORT_ALL_DECLARATION); let namespaceImports = exports.get(IMPORT_NAMESPACE_SPECIFIER); if (typeof namespaceImports === 'undefined') { namespaceImports = { whereUsed: new Set() }; } newExports.set(EXPORT_ALL_DECLARATION, exportAll); newExports.set(IMPORT_NAMESPACE_SPECIFIER, namespaceImports); exportList.set(file, newExports); }; /** * only useful for tools like vscode-eslint * * update lists of existing imports during runtime */ const updateImportUsage = node => { if (!unusedExports) { return; } let oldImportPaths = importList.get(file); if (typeof oldImportPaths === 'undefined') { oldImportPaths = new Map(); } const oldNamespaceImports = new Set(); const newNamespaceImports = new Set(); const oldExportAll = new Set(); const newExportAll = new Set(); const oldDefaultImports = new Set(); const newDefaultImports = new Set(); const oldImports = new Map(); const newImports = new Map(); oldImportPaths.forEach((value, key) => { if (value.has(EXPORT_ALL_DECLARATION)) { oldExportAll.add(key); } if (value.has(IMPORT_NAMESPACE_SPECIFIER)) { oldNamespaceImports.add(key); } if (value.has(IMPORT_DEFAULT_SPECIFIER)) { oldDefaultImports.add(key); } value.forEach(val => { if (val !== IMPORT_NAMESPACE_SPECIFIER && val !== IMPORT_DEFAULT_SPECIFIER) { oldImports.set(val, key); } }); }); node.body.forEach(astNode => { let resolvedPath; // support for export { value } from 'module' if (astNode.type === EXPORT_NAMED_DECLARATION) { if (astNode.source) { resolvedPath = (0, _resolve2.default)(astNode.source.raw.replace(/('|")/g, ''), context); astNode.specifiers.forEach(specifier => { let name; if (specifier.exported.name === DEFAULT) { name = IMPORT_DEFAULT_SPECIFIER; } else { name = specifier.local.name; } newImports.set(name, resolvedPath); }); } } if (astNode.type === EXPORT_ALL_DECLARATION) { resolvedPath = (0, _resolve2.default)(astNode.source.raw.replace(/('|")/g, ''), context); newExportAll.add(resolvedPath); } if (astNode.type === IMPORT_DECLARATION) { resolvedPath = (0, _resolve2.default)(astNode.source.raw.replace(/('|")/g, ''), context); if (!resolvedPath) { return; } if (isNodeModule(resolvedPath)) { return; } if (newNamespaceImportExists(astNode.specifiers)) { newNamespaceImports.add(resolvedPath); } if (newDefaultImportExists(astNode.specifiers)) { newDefaultImports.add(resolvedPath); } astNode.specifiers.forEach(specifier => { if (specifier.type === IMPORT_DEFAULT_SPECIFIER || specifier.type === IMPORT_NAMESPACE_SPECIFIER) { return; } newImports.set(specifier.imported.name, resolvedPath); }); } }); newExportAll.forEach(value => { if (!oldExportAll.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { imports = new Set(); } imports.add(EXPORT_ALL_DECLARATION); oldImportPaths.set(value, imports); let exports = exportList.get(value); let currentExport; if (typeof exports !== 'undefined') { currentExport = exports.get(EXPORT_ALL_DECLARATION); } else { exports = new Map(); exportList.set(value, exports); } if (typeof currentExport !== 'undefined') { currentExport.whereUsed.add(file); } else { const whereUsed = new Set(); whereUsed.add(file); exports.set(EXPORT_ALL_DECLARATION, { whereUsed }); } } }); oldExportAll.forEach(value => { if (!newExportAll.has(value)) { const imports = oldImportPaths.get(value); imports.delete(EXPORT_ALL_DECLARATION); const exports = exportList.get(value); if (typeof exports !== 'undefined') { const currentExport = exports.get(EXPORT_ALL_DECLARATION); if (typeof currentExport !== 'undefined') { currentExport.whereUsed.delete(file); } } } }); newDefaultImports.forEach(value => { if (!oldDefaultImports.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { imports = new Set(); } imports.add(IMPORT_DEFAULT_SPECIFIER); oldImportPaths.set(value, imports); let exports = exportList.get(value); let currentExport; if (typeof exports !== 'undefined') { currentExport = exports.get(IMPORT_DEFAULT_SPECIFIER); } else { exports = new Map(); exportList.set(value, exports); } if (typeof currentExport !== 'undefined') { currentExport.whereUsed.add(file); } else { const whereUsed = new Set(); whereUsed.add(file); exports.set(IMPORT_DEFAULT_SPECIFIER, { whereUsed }); } } }); oldDefaultImports.forEach(value => { if (!newDefaultImports.has(value)) { const imports = oldImportPaths.get(value); imports.delete(IMPORT_DEFAULT_SPECIFIER); const exports = exportList.get(value); if (typeof exports !== 'undefined') { const currentExport = exports.get(IMPORT_DEFAULT_SPECIFIER); if (typeof currentExport !== 'undefined') { currentExport.whereUsed.delete(file); } } } }); newNamespaceImports.forEach(value => { if (!oldNamespaceImports.has(value)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { imports = new Set(); } imports.add(IMPORT_NAMESPACE_SPECIFIER); oldImportPaths.set(value, imports); let exports = exportList.get(value); let currentExport; if (typeof exports !== 'undefined') { currentExport = exports.get(IMPORT_NAMESPACE_SPECIFIER); } else { exports = new Map(); exportList.set(value, exports); } if (typeof currentExport !== 'undefined') { currentExport.whereUsed.add(file); } else { const whereUsed = new Set(); whereUsed.add(file); exports.set(IMPORT_NAMESPACE_SPECIFIER, { whereUsed }); } } }); oldNamespaceImports.forEach(value => { if (!newNamespaceImports.has(value)) { const imports = oldImportPaths.get(value); imports.delete(IMPORT_NAMESPACE_SPECIFIER); const exports = exportList.get(value); if (typeof exports !== 'undefined') { const currentExport = exports.get(IMPORT_NAMESPACE_SPECIFIER); if (typeof currentExport !== 'undefined') { currentExport.whereUsed.delete(file); } } } }); newImports.forEach((value, key) => { if (!oldImports.has(key)) { let imports = oldImportPaths.get(value); if (typeof imports === 'undefined') { imports = new Set(); } imports.add(key); oldImportPaths.set(value, imports); let exports = exportList.get(value); let currentExport; if (typeof exports !== 'undefined') { currentExport = exports.get(key); } else { exports = new Map(); exportList.set(value, exports); } if (typeof currentExport !== 'undefined') { currentExport.whereUsed.add(file); } else { const whereUsed = new Set(); whereUsed.add(file); exports.set(key, { whereUsed }); } } }); oldImports.forEach((value, key) => { if (!newImports.has(key)) { const imports = oldImportPaths.get(value); imports.delete(key); const exports = exportList.get(value); if (typeof exports !== 'undefined') { const currentExport = exports.get(key); if (typeof currentExport !== 'undefined') { currentExport.whereUsed.delete(file); } } } }); }; return { 'Program:exit': node => { updateExportUsage(node); updateImportUsage(node); checkExportPresence(node); }, 'ExportDefaultDeclaration': node => { checkUsage(node, IMPORT_DEFAULT_SPECIFIER); }, 'ExportNamedDeclaration': node => { node.specifiers.forEach(specifier => { checkUsage(node, specifier.exported.name); }); if (node.declaration) { if (node.declaration.type === FUNCTION_DECLARATION || node.declaration.type === CLASS_DECLARATION || node.declaration.type === TYPE_ALIAS) { checkUsage(node, node.declaration.id.name); } if (node.declaration.type === VARIABLE_DECLARATION) { node.declaration.declarations.forEach(declaration => { checkUsage(node, declaration.id.name); }); } } } }; } }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby11bnVzZWQtbW9kdWxlcy5qcyJdLCJuYW1lcyI6WyJsaXN0RmlsZXNUb1Byb2Nlc3MiLCJGaWxlRW51bWVyYXRvciIsInJlcXVpcmUiLCJzcmMiLCJleHRlbnNpb25zIiwiZSIsIkFycmF5IiwiZnJvbSIsIml0ZXJhdGVGaWxlcyIsImZpbGVQYXRoIiwiaWdub3JlZCIsImZpbGVuYW1lIiwiZTEiLCJvcmlnaW5hbExpc3RGaWxlc1RvUHJvY2VzcyIsImUyIiwicGF0dGVybnMiLCJyZWR1Y2UiLCJjYXJyeSIsInBhdHRlcm4iLCJjb25jYXQiLCJtYXAiLCJleHRlbnNpb24iLCJ0ZXN0Iiwic2xpY2UiLCJFWFBPUlRfREVGQVVMVF9ERUNMQVJBVElPTiIsIkVYUE9SVF9OQU1FRF9ERUNMQVJBVElPTiIsIkVYUE9SVF9BTExfREVDTEFSQVRJT04iLCJJTVBPUlRfREVDTEFSQVRJT04iLCJJTVBPUlRfTkFNRVNQQUNFX1NQRUNJRklFUiIsIklNUE9SVF9ERUZBVUxUX1NQRUNJRklFUiIsIlZBUklBQkxFX0RFQ0xBUkFUSU9OIiwiRlVOQ1RJT05fREVDTEFSQVRJT04iLCJDTEFTU19ERUNMQVJBVElPTiIsIkRFRkFVTFQiLCJUWVBFX0FMSUFTIiwiaW1wb3J0TGlzdCIsIk1hcCIsImV4cG9ydExpc3QiLCJpZ25vcmVkRmlsZXMiLCJTZXQiLCJmaWxlc091dHNpZGVTcmMiLCJpc05vZGVNb2R1bGUiLCJwYXRoIiwicmVzb2x2ZUZpbGVzIiwiaWdub3JlRXhwb3J0cyIsImNvbnRleHQiLCJzZXR0aW5ncyIsInNyY0ZpbGVzIiwic3JjRmlsZUxpc3QiLCJpZ25vcmVkRmlsZXNMaXN0IiwiZm9yRWFjaCIsImFkZCIsImZpbHRlciIsInByZXBhcmVJbXBvcnRzQW5kRXhwb3J0cyIsImV4cG9ydEFsbCIsImZpbGUiLCJleHBvcnRzIiwiaW1wb3J0cyIsImN1cnJlbnRFeHBvcnRzIiwiRXhwb3J0cyIsImdldCIsImRlcGVuZGVuY2llcyIsInJlZXhwb3J0cyIsImxvY2FsSW1wb3J0TGlzdCIsIm5hbWVzcGFjZSIsImN1cnJlbnRFeHBvcnRBbGwiLCJnZXREZXBlbmRlbmN5IiwiZGVwZW5kZW5jeSIsInNldCIsInZhbHVlIiwia2V5Iiwid2hlcmVVc2VkIiwicmVleHBvcnQiLCJnZXRJbXBvcnQiLCJsb2NhbEltcG9ydCIsImN1cnJlbnRWYWx1ZSIsImxvY2FsIiwiaW1wb3J0ZWRTcGVjaWZpZXJzIiwiaGFzIiwidmFsIiwiY3VycmVudEV4cG9ydCIsImRldGVybWluZVVzYWdlIiwibGlzdFZhbHVlIiwibGlzdEtleSIsImN1cnJlbnRJbXBvcnQiLCJzcGVjaWZpZXIiLCJleHBvcnRTdGF0ZW1lbnQiLCJnZXRTcmMiLCJwcm9jZXNzIiwiY3dkIiwibGFzdFByZXBhcmVLZXkiLCJkb1ByZXBhcmF0aW9uIiwicHJlcGFyZUtleSIsIkpTT04iLCJzdHJpbmdpZnkiLCJzb3J0IiwiY2xlYXIiLCJuZXdOYW1lc3BhY2VJbXBvcnRFeGlzdHMiLCJzcGVjaWZpZXJzIiwic29tZSIsInR5cGUiLCJuZXdEZWZhdWx0SW1wb3J0RXhpc3RzIiwiZmlsZUlzSW5Qa2ciLCJyZWFkUGtnVXAiLCJzeW5jIiwibm9ybWFsaXplIiwicGtnIiwiYmFzZVBhdGgiLCJjaGVja1BrZ0ZpZWxkU3RyaW5nIiwicGtnRmllbGQiLCJjaGVja1BrZ0ZpZWxkT2JqZWN0IiwicGtnRmllbGRGaWxlcyIsImNoZWNrUGtnRmllbGQiLCJwcml2YXRlIiwiYmluIiwiYnJvd3NlciIsIm1haW4iLCJtb2R1bGUiLCJtZXRhIiwiZG9jcyIsInVybCIsInNjaGVtYSIsInByb3BlcnRpZXMiLCJkZXNjcmlwdGlvbiIsIm1pbkl0ZW1zIiwiaXRlbXMiLCJtaW5MZW5ndGgiLCJtaXNzaW5nRXhwb3J0cyIsInVudXNlZEV4cG9ydHMiLCJub3QiLCJlbnVtIiwiYW55T2YiLCJyZXF1aXJlZCIsImNyZWF0ZSIsIm9wdGlvbnMiLCJnZXRGaWxlbmFtZSIsImNoZWNrRXhwb3J0UHJlc2VuY2UiLCJub2RlIiwiZXhwb3J0Q291bnQiLCJuYW1lc3BhY2VJbXBvcnRzIiwiZGVsZXRlIiwic2l6ZSIsInJlcG9ydCIsImJvZHkiLCJjaGVja1VzYWdlIiwiZXhwb3J0ZWRWYWx1ZSIsInVwZGF0ZUV4cG9ydFVzYWdlIiwibmV3RXhwb3J0cyIsIm5ld0V4cG9ydElkZW50aWZpZXJzIiwiZGVjbGFyYXRpb24iLCJsZW5ndGgiLCJleHBvcnRlZCIsIm5hbWUiLCJpZCIsImRlY2xhcmF0aW9ucyIsInVwZGF0ZUltcG9ydFVzYWdlIiwib2xkSW1wb3J0UGF0aHMiLCJvbGROYW1lc3BhY2VJbXBvcnRzIiwibmV3TmFtZXNwYWNlSW1wb3J0cyIsIm9sZEV4cG9ydEFsbCIsIm5ld0V4cG9ydEFsbCIsIm9sZERlZmF1bHRJbXBvcnRzIiwibmV3RGVmYXVsdEltcG9ydHMiLCJvbGRJbXBvcnRzIiwibmV3SW1wb3J0cyIsImFzdE5vZGUiLCJyZXNvbHZlZFBhdGgiLCJzb3VyY2UiLCJyYXciLCJyZXBsYWNlIiwiaW1wb3J0ZWQiXSwibWFwcGluZ3MiOiI7O0FBTUE7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Z01BYkE7Ozs7OztBQWVBO0FBQ0E7QUFDQSxJQUFJQSxrQkFBSjtBQUNBLElBQUk7QUFDRixRQUFNQyxpQkFBaUJDLFFBQVEsdUNBQVIsRUFBaURELGNBQXhFO0FBQ0FELHVCQUFxQixVQUFVRyxHQUFWLEVBQWVDLFVBQWYsRUFBMkI7QUFDOUMsVUFBTUMsSUFBSSxJQUFJSixjQUFKLENBQW1CO0FBQzNCRyxrQkFBWUE7QUFEZSxLQUFuQixDQUFWO0FBR0EsV0FBT0UsTUFBTUMsSUFBTixDQUFXRixFQUFFRyxZQUFGLENBQWVMLEdBQWYsQ0FBWCxFQUFnQztBQUFBLFVBQUdNLFFBQUgsUUFBR0EsUUFBSDtBQUFBLFVBQWFDLE9BQWIsUUFBYUEsT0FBYjtBQUFBLGFBQTRCO0FBQ2pFQSxlQURpRTtBQUVqRUMsa0JBQVVGO0FBRnVELE9BQTVCO0FBQUEsS0FBaEMsQ0FBUDtBQUlELEdBUkQ7QUFTRCxDQVhELENBV0UsT0FBT0csRUFBUCxFQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsTUFBSUMsMEJBQUo7QUFDQSxNQUFJO0FBQ0ZBLGlDQUE2QlgsUUFBUSw0QkFBUixFQUFzQ0Ysa0JBQW5FO0FBQ0FBLHlCQUFxQixVQUFVRyxHQUFWLEVBQWVDLFVBQWYsRUFBMkI7QUFDOUMsYUFBT1MsMkJBQTJCVixHQUEzQixFQUFnQztBQUNyQ0Msb0JBQVlBO0FBRHlCLE9BQWhDLENBQVA7QUFHRCxLQUpEO0FBS0QsR0FQRCxDQU9FLE9BQU9VLEVBQVAsRUFBVztBQUNYRCxpQ0FBNkJYLFFBQVEsMkJBQVIsRUFBcUNGLGtCQUFsRTs7QUFFQUEseUJBQXFCLFVBQVVHLEdBQVYsRUFBZUMsVUFBZixFQUEyQjtBQUM5QyxZQUFNVyxXQUFXWixJQUFJYSxNQUFKLENBQVcsQ0FBQ0MsS0FBRCxFQUFRQyxPQUFSLEtBQW9CO0FBQzlDLGVBQU9ELE1BQU1FLE1BQU4sQ0FBYWYsV0FBV2dCLEdBQVgsQ0FBZ0JDLFNBQUQsSUFBZTtBQUNoRCxpQkFBTyxhQUFZQyxJQUFaLENBQWlCSixPQUFqQixJQUE0QkEsT0FBNUIsR0FBdUMsR0FBRUEsT0FBUSxRQUFPRyxTQUFVO0FBQXpFO0FBQ0QsU0FGbUIsQ0FBYixDQUFQO0FBR0QsT0FKZ0IsRUFJZGxCLElBQUlvQixLQUFKLEVBSmMsQ0FBakI7O0FBTUEsYUFBT1YsMkJBQTJCRSxRQUEzQixDQUFQO0FBQ0QsS0FSRDtBQVNEO0FBQ0Y7O0FBRUQsTUFBTVMsNkJBQTZCLDBCQUFuQztBQUNBLE1BQU1DLDJCQUEyQix3QkFBakM7QUFDQSxNQUFNQyx5QkFBeUIsc0JBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLG1CQUEzQjtBQUNBLE1BQU1DLDZCQUE2QiwwQkFBbkM7QUFDQSxNQUFNQywyQkFBMkIsd0JBQWpDO0FBQ0EsTUFBTUMsdUJBQXVCLHFCQUE3QjtBQUNBLE1BQU1DLHVCQUF1QixxQkFBN0I7QUFDQSxNQUFNQyxvQkFBb0Isa0JBQTFCO0FBQ0EsTUFBTUMsVUFBVSxTQUFoQjtBQUNBLE1BQU1DLGFBQWEsV0FBbkI7O0FBRUEsTUFBTUMsYUFBYSxJQUFJQyxHQUFKLEVBQW5CO0FBQ0EsTUFBTUMsYUFBYSxJQUFJRCxHQUFKLEVBQW5CO0FBQ0EsTUFBTUUsZUFBZSxJQUFJQyxHQUFKLEVBQXJCO0FBQ0EsTUFBTUMsa0JBQWtCLElBQUlELEdBQUosRUFBeEI7O0FBRUEsTUFBTUUsZUFBZUMsUUFBUTtBQUMzQixTQUFPLHNCQUFxQnBCLElBQXJCLENBQTBCb0IsSUFBMUI7QUFBUDtBQUNELENBRkQ7O0FBSUE7Ozs7O0FBS0EsTUFBTUMsZUFBZSxDQUFDeEMsR0FBRCxFQUFNeUMsYUFBTixFQUFxQkMsT0FBckIsS0FBaUM7QUFDcEQsUUFBTXpDLGFBQWFFLE1BQU1DLElBQU4sQ0FBVywrQkFBa0JzQyxRQUFRQyxRQUExQixDQUFYLENBQW5COztBQUVBLFFBQU1DLFdBQVcsSUFBSVIsR0FBSixFQUFqQjtBQUNBLFFBQU1TLGNBQWNoRCxtQkFBbUJHLEdBQW5CLEVBQXdCQyxVQUF4QixDQUFwQjs7QUFFQTtBQUNBLFFBQU02QyxtQkFBb0JqRCxtQkFBbUI0QyxhQUFuQixFQUFrQ3hDLFVBQWxDLENBQTFCO0FBQ0E2QyxtQkFBaUJDLE9BQWpCLENBQXlCO0FBQUEsUUFBR3ZDLFFBQUgsU0FBR0EsUUFBSDtBQUFBLFdBQWtCMkIsYUFBYWEsR0FBYixDQUFpQnhDLFFBQWpCLENBQWxCO0FBQUEsR0FBekI7O0FBRUE7QUFDQXFDLGNBQVlJLE1BQVosQ0FBbUI7QUFBQSxRQUFHekMsUUFBSCxTQUFHQSxRQUFIO0FBQUEsV0FBa0IsQ0FBQzhCLGFBQWE5QixRQUFiLENBQW5CO0FBQUEsR0FBbkIsRUFBOER1QyxPQUE5RCxDQUFzRSxXQUFrQjtBQUFBLFFBQWZ2QyxRQUFlLFNBQWZBLFFBQWU7O0FBQ3RGb0MsYUFBU0ksR0FBVCxDQUFheEMsUUFBYjtBQUNELEdBRkQ7QUFHQSxTQUFPb0MsUUFBUDtBQUNELENBZkQ7O0FBaUJBOzs7QUFHQSxNQUFNTSwyQkFBMkIsQ0FBQ04sUUFBRCxFQUFXRixPQUFYLEtBQXVCO0FBQ3RELFFBQU1TLFlBQVksSUFBSWxCLEdBQUosRUFBbEI7QUFDQVcsV0FBU0csT0FBVCxDQUFpQkssUUFBUTtBQUN2QixVQUFNQyxVQUFVLElBQUlwQixHQUFKLEVBQWhCO0FBQ0EsVUFBTXFCLFVBQVUsSUFBSXJCLEdBQUosRUFBaEI7QUFDQSxVQUFNc0IsaUJBQWlCQyxvQkFBUUMsR0FBUixDQUFZTCxJQUFaLEVBQWtCVixPQUFsQixDQUF2QjtBQUNBLFFBQUlhLGNBQUosRUFBb0I7QUFBQSxZQUNWRyxZQURVLEdBQ3dESCxjQUR4RCxDQUNWRyxZQURVO0FBQUEsWUFDSUMsU0FESixHQUN3REosY0FEeEQsQ0FDSUksU0FESjtBQUFBLFlBQ3dCQyxlQUR4QixHQUN3REwsY0FEeEQsQ0FDZUQsT0FEZjtBQUFBLFlBQ3lDTyxTQUR6QyxHQUN3RE4sY0FEeEQsQ0FDeUNNLFNBRHpDOztBQUdsQjs7QUFDQSxZQUFNQyxtQkFBbUIsSUFBSTFCLEdBQUosRUFBekI7QUFDQXNCLG1CQUFhWCxPQUFiLENBQXFCZ0IsaUJBQWlCO0FBQ3BDLGNBQU1DLGFBQWFELGVBQW5CO0FBQ0EsWUFBSUMsZUFBZSxJQUFuQixFQUF5QjtBQUN2QjtBQUNEOztBQUVERix5QkFBaUJkLEdBQWpCLENBQXFCZ0IsV0FBV3pCLElBQWhDO0FBQ0QsT0FQRDtBQVFBWSxnQkFBVWMsR0FBVixDQUFjYixJQUFkLEVBQW9CVSxnQkFBcEI7O0FBRUFILGdCQUFVWixPQUFWLENBQWtCLENBQUNtQixLQUFELEVBQVFDLEdBQVIsS0FBZ0I7QUFDaEMsWUFBSUEsUUFBUXJDLE9BQVosRUFBcUI7QUFDbkJ1QixrQkFBUVksR0FBUixDQUFZdkMsd0JBQVosRUFBc0MsRUFBRTBDLFdBQVcsSUFBSWhDLEdBQUosRUFBYixFQUF0QztBQUNELFNBRkQsTUFFTztBQUNMaUIsa0JBQVFZLEdBQVIsQ0FBWUUsR0FBWixFQUFpQixFQUFFQyxXQUFXLElBQUloQyxHQUFKLEVBQWIsRUFBakI7QUFDRDtBQUNELGNBQU1pQyxXQUFZSCxNQUFNSSxTQUFOLEVBQWxCO0FBQ0EsWUFBSSxDQUFDRCxRQUFMLEVBQWU7QUFDYjtBQUNEO0FBQ0QsWUFBSUUsY0FBY2pCLFFBQVFHLEdBQVIsQ0FBWVksU0FBUzlCLElBQXJCLENBQWxCO0FBQ0EsWUFBSWlDLFlBQUo7QUFDQSxZQUFJTixNQUFNTyxLQUFOLEtBQWdCM0MsT0FBcEIsRUFBNkI7QUFDM0IwQyx5QkFBZTlDLHdCQUFmO0FBQ0QsU0FGRCxNQUVPO0FBQ0w4Qyx5QkFBZU4sTUFBTU8sS0FBckI7QUFDRDtBQUNELFlBQUksT0FBT0YsV0FBUCxLQUF1QixXQUEzQixFQUF3QztBQUN0Q0Esd0JBQWMsSUFBSW5DLEdBQUosOEJBQVltQyxXQUFaLElBQXlCQyxZQUF6QixHQUFkO0FBQ0QsU0FGRCxNQUVPO0FBQ0xELHdCQUFjLElBQUluQyxHQUFKLENBQVEsQ0FBQ29DLFlBQUQsQ0FBUixDQUFkO0FBQ0Q7QUFDRGxCLGdCQUFRVyxHQUFSLENBQVlJLFNBQVM5QixJQUFyQixFQUEyQmdDLFdBQTNCO0FBQ0QsT0F2QkQ7O0FBeUJBWCxzQkFBZ0JiLE9BQWhCLENBQXdCLENBQUNtQixLQUFELEVBQVFDLEdBQVIsS0FBZ0I7QUFDdEMsWUFBSTdCLGFBQWE2QixHQUFiLENBQUosRUFBdUI7QUFDckI7QUFDRDtBQUNEYixnQkFBUVcsR0FBUixDQUFZRSxHQUFaLEVBQWlCRCxNQUFNUSxrQkFBdkI7QUFDRCxPQUxEO0FBTUExQyxpQkFBV2lDLEdBQVgsQ0FBZWIsSUFBZixFQUFxQkUsT0FBckI7O0FBRUE7QUFDQSxVQUFJbkIsYUFBYXdDLEdBQWIsQ0FBaUJ2QixJQUFqQixDQUFKLEVBQTRCO0FBQzFCO0FBQ0Q7QUFDRFMsZ0JBQVVkLE9BQVYsQ0FBa0IsQ0FBQ21CLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNoQyxZQUFJQSxRQUFRckMsT0FBWixFQUFxQjtBQUNuQnVCLGtCQUFRWSxHQUFSLENBQVl2Qyx3QkFBWixFQUFzQyxFQUFFMEMsV0FBVyxJQUFJaEMsR0FBSixFQUFiLEVBQXRDO0FBQ0QsU0FGRCxNQUVPO0FBQ0xpQixrQkFBUVksR0FBUixDQUFZRSxHQUFaLEVBQWlCLEVBQUVDLFdBQVcsSUFBSWhDLEdBQUosRUFBYixFQUFqQjtBQUNEO0FBQ0YsT0FORDtBQU9EO0FBQ0RpQixZQUFRWSxHQUFSLENBQVkxQyxzQkFBWixFQUFvQyxFQUFFNkMsV0FBVyxJQUFJaEMsR0FBSixFQUFiLEVBQXBDO0FBQ0FpQixZQUFRWSxHQUFSLENBQVl4QywwQkFBWixFQUF3QyxFQUFFMkMsV0FBVyxJQUFJaEMsR0FBSixFQUFiLEVBQXhDO0FBQ0FGLGVBQVcrQixHQUFYLENBQWViLElBQWYsRUFBcUJDLE9BQXJCO0FBQ0QsR0FuRUQ7QUFvRUFGLFlBQVVKLE9BQVYsQ0FBa0IsQ0FBQ21CLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNoQ0QsVUFBTW5CLE9BQU4sQ0FBYzZCLE9BQU87QUFDbkIsWUFBTXJCLGlCQUFpQnJCLFdBQVd1QixHQUFYLENBQWVtQixHQUFmLENBQXZCO0FBQ0EsWUFBTUMsZ0JBQWdCdEIsZUFBZUUsR0FBZixDQUFtQmxDLHNCQUFuQixDQUF0QjtBQUNBc0Qsb0JBQWNULFNBQWQsQ0FBd0JwQixHQUF4QixDQUE0Qm1CLEdBQTVCO0FBQ0QsS0FKRDtBQUtELEdBTkQ7QUFPRCxDQTdFRDs7QUErRUE7Ozs7QUFJQSxNQUFNVyxpQkFBaUIsTUFBTTtBQUMzQjlDLGFBQVdlLE9BQVgsQ0FBbUIsQ0FBQ2dDLFNBQUQsRUFBWUMsT0FBWixLQUF3QjtBQUN6Q0QsY0FBVWhDLE9BQVYsQ0FBa0IsQ0FBQ21CLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNoQyxZQUFNZCxVQUFVbkIsV0FBV3VCLEdBQVgsQ0FBZVUsR0FBZixDQUFoQjtBQUNBLFVBQUksT0FBT2QsT0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQ2EsY0FBTW5CLE9BQU4sQ0FBY2tDLGlCQUFpQjtBQUM3QixjQUFJQyxTQUFKO0FBQ0EsY0FBSUQsa0JBQWtCeEQsMEJBQXRCLEVBQWtEO0FBQ2hEeUQsd0JBQVl6RCwwQkFBWjtBQUNELFdBRkQsTUFFTyxJQUFJd0Qsa0JBQWtCdkQsd0JBQXRCLEVBQWdEO0FBQ3JEd0Qsd0JBQVl4RCx3QkFBWjtBQUNELFdBRk0sTUFFQTtBQUNMd0Qsd0JBQVlELGFBQVo7QUFDRDtBQUNELGNBQUksT0FBT0MsU0FBUCxLQUFxQixXQUF6QixFQUFzQztBQUNwQyxrQkFBTUMsa0JBQWtCOUIsUUFBUUksR0FBUixDQUFZeUIsU0FBWixDQUF4QjtBQUNBLGdCQUFJLE9BQU9DLGVBQVAsS0FBMkIsV0FBL0IsRUFBNEM7QUFBQSxvQkFDbENmLFNBRGtDLEdBQ3BCZSxlQURvQixDQUNsQ2YsU0FEa0M7O0FBRTFDQSx3QkFBVXBCLEdBQVYsQ0FBY2dDLE9BQWQ7QUFDQTNCLHNCQUFRWSxHQUFSLENBQVlpQixTQUFaLEVBQXVCLEVBQUVkLFNBQUYsRUFBdkI7QUFDRDtBQUNGO0FBQ0YsU0FqQkQ7QUFrQkQ7QUFDRixLQXRCRDtBQXVCRCxHQXhCRDtBQXlCRCxDQTFCRDs7QUE0QkEsTUFBTWdCLFNBQVNwRixPQUFPO0FBQ3BCLE1BQUlBLEdBQUosRUFBUztBQUNQLFdBQU9BLEdBQVA7QUFDRDtBQUNELFNBQU8sQ0FBQ3FGLFFBQVFDLEdBQVIsRUFBRCxDQUFQO0FBQ0QsQ0FMRDs7QUFPQTs7OztBQUlBLElBQUkxQyxRQUFKO0FBQ0EsSUFBSTJDLGNBQUo7QUFDQSxNQUFNQyxnQkFBZ0IsQ0FBQ3hGLEdBQUQsRUFBTXlDLGFBQU4sRUFBcUJDLE9BQXJCLEtBQWlDO0FBQ3JELFFBQU0rQyxhQUFhQyxLQUFLQyxTQUFMLENBQWU7QUFDaEMzRixTQUFLLENBQUNBLE9BQU8sRUFBUixFQUFZNEYsSUFBWixFQUQyQjtBQUVoQ25ELG1CQUFlLENBQUNBLGlCQUFpQixFQUFsQixFQUFzQm1ELElBQXRCLEVBRmlCO0FBR2hDM0YsZ0JBQVlFLE1BQU1DLElBQU4sQ0FBVywrQkFBa0JzQyxRQUFRQyxRQUExQixDQUFYLEVBQWdEaUQsSUFBaEQ7QUFIb0IsR0FBZixDQUFuQjtBQUtBLE1BQUlILGVBQWVGLGNBQW5CLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBRUR2RCxhQUFXNkQsS0FBWDtBQUNBM0QsYUFBVzJELEtBQVg7QUFDQTFELGVBQWEwRCxLQUFiO0FBQ0F4RCxrQkFBZ0J3RCxLQUFoQjs7QUFFQWpELGFBQVdKLGFBQWE0QyxPQUFPcEYsR0FBUCxDQUFiLEVBQTBCeUMsYUFBMUIsRUFBeUNDLE9BQXpDLENBQVg7QUFDQVEsMkJBQXlCTixRQUF6QixFQUFtQ0YsT0FBbkM7QUFDQW9DO0FBQ0FTLG1CQUFpQkUsVUFBakI7QUFDRCxDQW5CRDs7QUFxQkEsTUFBTUssMkJBQTJCQyxjQUMvQkEsV0FBV0MsSUFBWCxDQUFnQjtBQUFBLE1BQUdDLElBQUgsU0FBR0EsSUFBSDtBQUFBLFNBQWNBLFNBQVN4RSwwQkFBdkI7QUFBQSxDQUFoQixDQURGOztBQUdBLE1BQU15RSx5QkFBeUJILGNBQzdCQSxXQUFXQyxJQUFYLENBQWdCO0FBQUEsTUFBR0MsSUFBSCxTQUFHQSxJQUFIO0FBQUEsU0FBY0EsU0FBU3ZFLHdCQUF2QjtBQUFBLENBQWhCLENBREY7O0FBR0EsTUFBTXlFLGNBQWMvQyxRQUFRO0FBQUEsd0JBQ0pnRCxvQkFBVUMsSUFBVixDQUFlLEVBQUNmLEtBQUtsQyxJQUFOLEVBQVlrRCxXQUFXLEtBQXZCLEVBQWYsQ0FESTs7QUFBQSxRQUNsQi9ELElBRGtCLG1CQUNsQkEsSUFEa0I7QUFBQSxRQUNaZ0UsR0FEWSxtQkFDWkEsR0FEWTs7QUFFMUIsUUFBTUMsV0FBVyxtQkFBUWpFLElBQVIsQ0FBakI7O0FBRUEsUUFBTWtFLHNCQUFzQkMsWUFBWTtBQUN0QyxRQUFJLGdCQUFLRixRQUFMLEVBQWVFLFFBQWYsTUFBNkJ0RCxJQUFqQyxFQUF1QztBQUNuQyxhQUFPLElBQVA7QUFDRDtBQUNKLEdBSkQ7O0FBTUEsUUFBTXVELHNCQUFzQkQsWUFBWTtBQUNwQyxVQUFNRSxnQkFBZ0Isc0JBQU9GLFFBQVAsRUFBaUJ6RixHQUFqQixDQUFxQmlELFNBQVMsZ0JBQUtzQyxRQUFMLEVBQWV0QyxLQUFmLENBQTlCLENBQXRCO0FBQ0EsUUFBSSw2QkFBUzBDLGFBQVQsRUFBd0J4RCxJQUF4QixDQUFKLEVBQW1DO0FBQ2pDLGFBQU8sSUFBUDtBQUNEO0FBQ0osR0FMRDs7QUFPQSxRQUFNeUQsZ0JBQWdCSCxZQUFZO0FBQ2hDLFFBQUksT0FBT0EsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUNoQyxhQUFPRCxvQkFBb0JDLFFBQXBCLENBQVA7QUFDRDs7QUFFRCxRQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBeEIsRUFBa0M7QUFDaEMsYUFBT0Msb0JBQW9CRCxRQUFwQixDQUFQO0FBQ0Q7QUFDRixHQVJEOztBQVVBLE1BQUlILElBQUlPLE9BQUosS0FBZ0IsSUFBcEIsRUFBMEI7QUFDeEIsV0FBTyxLQUFQO0FBQ0Q7O0FBRUQsTUFBSVAsSUFBSVEsR0FBUixFQUFhO0FBQ1gsUUFBSUYsY0FBY04sSUFBSVEsR0FBbEIsQ0FBSixFQUE0QjtBQUMxQixhQUFPLElBQVA7QUFDRDtBQUNGOztBQUVELE1BQUlSLElBQUlTLE9BQVIsRUFBaUI7QUFDZixRQUFJSCxjQUFjTixJQUFJUyxPQUFsQixDQUFKLEVBQWdDO0FBQzlCLGFBQU8sSUFBUDtBQUNEO0FBQ0Y7O0FBRUQsTUFBSVQsSUFBSVUsSUFBUixFQUFjO0FBQ1osUUFBSVIsb0JBQW9CRixJQUFJVSxJQUF4QixDQUFKLEVBQW1DO0FBQ2pDLGFBQU8sSUFBUDtBQUNEO0FBQ0Y7O0FBRUQsU0FBTyxLQUFQO0FBQ0QsQ0FsREQ7O0FBb0RBQyxPQUFPN0QsT0FBUCxHQUFpQjtBQUNmOEQsUUFBTTtBQUNKbEIsVUFBTSxZQURGO0FBRUptQixVQUFNLEVBQUVDLEtBQUssdUJBQVEsbUJBQVIsQ0FBUCxFQUZGO0FBR0pDLFlBQVEsQ0FBQztBQUNQQyxrQkFBWTtBQUNWdkgsYUFBSztBQUNId0gsdUJBQWEsc0RBRFY7QUFFSHZCLGdCQUFNLE9BRkg7QUFHSHdCLG9CQUFVLENBSFA7QUFJSEMsaUJBQU87QUFDTHpCLGtCQUFNLFFBREQ7QUFFTDBCLHVCQUFXO0FBRk47QUFKSixTQURLO0FBVVZsRix1QkFBZTtBQUNiK0UsdUJBQ0UscUZBRlc7QUFHYnZCLGdCQUFNLE9BSE87QUFJYndCLG9CQUFVLENBSkc7QUFLYkMsaUJBQU87QUFDTHpCLGtCQUFNLFFBREQ7QUFFTDBCLHVCQUFXO0FBRk47QUFMTSxTQVZMO0FBb0JWQyx3QkFBZ0I7QUFDZEosdUJBQWEsb0NBREM7QUFFZHZCLGdCQUFNO0FBRlEsU0FwQk47QUF3QlY0Qix1QkFBZTtBQUNiTCx1QkFBYSxrQ0FEQTtBQUVidkIsZ0JBQU07QUFGTztBQXhCTCxPQURMO0FBOEJQNkIsV0FBSztBQUNIUCxvQkFBWTtBQUNWTSx5QkFBZSxFQUFFRSxNQUFNLENBQUMsS0FBRCxDQUFSLEVBREw7QUFFVkgsMEJBQWdCLEVBQUVHLE1BQU0sQ0FBQyxLQUFELENBQVI7QUFGTjtBQURULE9BOUJFO0FBb0NQQyxhQUFNLENBQUM7QUFDTEYsYUFBSztBQUNIUCxzQkFBWTtBQUNWTSwyQkFBZSxFQUFFRSxNQUFNLENBQUMsSUFBRCxDQUFSO0FBREw7QUFEVCxTQURBO0FBTUxFLGtCQUFVLENBQUMsZ0JBQUQ7QUFOTCxPQUFELEVBT0g7QUFDREgsYUFBSztBQUNIUCxzQkFBWTtBQUNWSyw0QkFBZ0IsRUFBRUcsTUFBTSxDQUFDLElBQUQsQ0FBUjtBQUROO0FBRFQsU0FESjtBQU1ERSxrQkFBVSxDQUFDLGVBQUQ7QUFOVCxPQVBHLEVBY0g7QUFDRFYsb0JBQVk7QUFDVk0seUJBQWUsRUFBRUUsTUFBTSxDQUFDLElBQUQsQ0FBUjtBQURMLFNBRFg7QUFJREUsa0JBQVUsQ0FBQyxlQUFEO0FBSlQsT0FkRyxFQW1CSDtBQUNEVixvQkFBWTtBQUNWSywwQkFBZ0IsRUFBRUcsTUFBTSxDQUFDLElBQUQsQ0FBUjtBQUROLFNBRFg7QUFJREUsa0JBQVUsQ0FBQyxnQkFBRDtBQUpULE9BbkJHO0FBcENDLEtBQUQ7QUFISixHQURTOztBQW9FZkMsVUFBUXhGLFdBQVc7QUFBQSxnQkFNYkEsUUFBUXlGLE9BQVIsQ0FBZ0IsQ0FBaEIsS0FBc0IsRUFOVDs7QUFBQSxVQUVmbkksR0FGZSxTQUVmQSxHQUZlO0FBQUEsb0NBR2Z5QyxhQUhlO0FBQUEsVUFHZkEsYUFIZSx1Q0FHQyxFQUhEO0FBQUEsVUFJZm1GLGNBSmUsU0FJZkEsY0FKZTtBQUFBLFVBS2ZDLGFBTGUsU0FLZkEsYUFMZTs7O0FBUWpCLFFBQUlBLGFBQUosRUFBbUI7QUFDakJyQyxvQkFBY3hGLEdBQWQsRUFBbUJ5QyxhQUFuQixFQUFrQ0MsT0FBbEM7QUFDRDs7QUFFRCxVQUFNVSxPQUFPVixRQUFRMEYsV0FBUixFQUFiOztBQUVBLFVBQU1DLHNCQUFzQkMsUUFBUTtBQUNsQyxVQUFJLENBQUNWLGNBQUwsRUFBcUI7QUFDbkI7QUFDRDs7QUFFRCxVQUFJekYsYUFBYXdDLEdBQWIsQ0FBaUJ2QixJQUFqQixDQUFKLEVBQTRCO0FBQzFCO0FBQ0Q7O0FBRUQsWUFBTW1GLGNBQWNyRyxXQUFXdUIsR0FBWCxDQUFlTCxJQUFmLENBQXBCO0FBQ0EsWUFBTUQsWUFBWW9GLFlBQVk5RSxHQUFaLENBQWdCbEMsc0JBQWhCLENBQWxCO0FBQ0EsWUFBTWlILG1CQUFtQkQsWUFBWTlFLEdBQVosQ0FBZ0JoQywwQkFBaEIsQ0FBekI7O0FBRUE4RyxrQkFBWUUsTUFBWixDQUFtQmxILHNCQUFuQjtBQUNBZ0gsa0JBQVlFLE1BQVosQ0FBbUJoSCwwQkFBbkI7QUFDQSxVQUFJOEcsWUFBWUcsSUFBWixHQUFtQixDQUF2QixFQUEwQjtBQUN4QjtBQUNBO0FBQ0FoRyxnQkFBUWlHLE1BQVIsQ0FBZUwsS0FBS00sSUFBTCxDQUFVLENBQVYsSUFBZU4sS0FBS00sSUFBTCxDQUFVLENBQVYsQ0FBZixHQUE4Qk4sSUFBN0MsRUFBbUQsa0JBQW5EO0FBQ0Q7QUFDREMsa0JBQVl0RSxHQUFaLENBQWdCMUMsc0JBQWhCLEVBQXdDNEIsU0FBeEM7QUFDQW9GLGtCQUFZdEUsR0FBWixDQUFnQnhDLDBCQUFoQixFQUE0QytHLGdCQUE1QztBQUNELEtBdEJEOztBQXdCQSxVQUFNSyxhQUFhLENBQUNQLElBQUQsRUFBT1EsYUFBUCxLQUF5QjtBQUMxQyxVQUFJLENBQUNqQixhQUFMLEVBQW9CO0FBQ2xCO0FBQ0Q7O0FBRUQsVUFBSTFGLGFBQWF3QyxHQUFiLENBQWlCdkIsSUFBakIsQ0FBSixFQUE0QjtBQUMxQjtBQUNEOztBQUVELFVBQUkrQyxZQUFZL0MsSUFBWixDQUFKLEVBQXVCO0FBQ3JCO0FBQ0Q7O0FBRUQsVUFBSWYsZ0JBQWdCc0MsR0FBaEIsQ0FBb0J2QixJQUFwQixDQUFKLEVBQStCO0FBQzdCO0FBQ0Q7O0FBRUQ7QUFDQSxVQUFJLENBQUNSLFNBQVMrQixHQUFULENBQWF2QixJQUFiLENBQUwsRUFBeUI7QUFDdkJSLG1CQUFXSixhQUFhNEMsT0FBT3BGLEdBQVAsQ0FBYixFQUEwQnlDLGFBQTFCLEVBQXlDQyxPQUF6QyxDQUFYO0FBQ0EsWUFBSSxDQUFDRSxTQUFTK0IsR0FBVCxDQUFhdkIsSUFBYixDQUFMLEVBQXlCO0FBQ3ZCZiwwQkFBZ0JXLEdBQWhCLENBQW9CSSxJQUFwQjtBQUNBO0FBQ0Q7QUFDRjs7QUFFREMsZ0JBQVVuQixXQUFXdUIsR0FBWCxDQUFlTCxJQUFmLENBQVY7O0FBRUE7QUFDQSxZQUFNRCxZQUFZRSxRQUFRSSxHQUFSLENBQVlsQyxzQkFBWixDQUFsQjtBQUNBLFVBQUksT0FBTzRCLFNBQVAsS0FBcUIsV0FBckIsSUFBb0MyRixrQkFBa0JwSCx3QkFBMUQsRUFBb0Y7QUFDbEYsWUFBSXlCLFVBQVVpQixTQUFWLENBQW9Cc0UsSUFBcEIsR0FBMkIsQ0FBL0IsRUFBa0M7QUFDaEM7QUFDRDtBQUNGOztBQUVEO0FBQ0EsWUFBTUYsbUJBQW1CbkYsUUFBUUksR0FBUixDQUFZaEMsMEJBQVosQ0FBekI7QUFDQSxVQUFJLE9BQU8rRyxnQkFBUCxLQUE0QixXQUFoQyxFQUE2QztBQUMzQyxZQUFJQSxpQkFBaUJwRSxTQUFqQixDQUEyQnNFLElBQTNCLEdBQWtDLENBQXRDLEVBQXlDO0FBQ3ZDO0FBQ0Q7QUFDRjs7QUFFRCxZQUFNdkQsa0JBQWtCOUIsUUFBUUksR0FBUixDQUFZcUYsYUFBWixDQUF4Qjs7QUFFQSxZQUFNNUUsUUFBUTRFLGtCQUFrQnBILHdCQUFsQixHQUE2Q0ksT0FBN0MsR0FBdURnSCxhQUFyRTs7QUFFQSxVQUFJLE9BQU8zRCxlQUFQLEtBQTJCLFdBQS9CLEVBQTJDO0FBQ3pDLFlBQUlBLGdCQUFnQmYsU0FBaEIsQ0FBMEJzRSxJQUExQixHQUFpQyxDQUFyQyxFQUF3QztBQUN0Q2hHLGtCQUFRaUcsTUFBUixDQUNFTCxJQURGLEVBRUcseUJBQXdCcEUsS0FBTSxpQ0FGakM7QUFJRDtBQUNGLE9BUEQsTUFPTztBQUNMeEIsZ0JBQVFpRyxNQUFSLENBQ0VMLElBREYsRUFFRyx5QkFBd0JwRSxLQUFNLGlDQUZqQztBQUlEO0FBQ0YsS0E3REQ7O0FBK0RBOzs7OztBQUtBLFVBQU02RSxvQkFBb0JULFFBQVE7QUFDaEMsVUFBSW5HLGFBQWF3QyxHQUFiLENBQWlCdkIsSUFBakIsQ0FBSixFQUE0QjtBQUMxQjtBQUNEOztBQUVELFVBQUlDLFVBQVVuQixXQUFXdUIsR0FBWCxDQUFlTCxJQUFmLENBQWQ7O0FBRUE7QUFDQTtBQUNBLFVBQUksT0FBT0MsT0FBUCxLQUFtQixXQUF2QixFQUFvQztBQUNsQ0Esa0JBQVUsSUFBSXBCLEdBQUosRUFBVjtBQUNEOztBQUVELFlBQU0rRyxhQUFhLElBQUkvRyxHQUFKLEVBQW5CO0FBQ0EsWUFBTWdILHVCQUF1QixJQUFJN0csR0FBSixFQUE3Qjs7QUFFQWtHLFdBQUtNLElBQUwsQ0FBVTdGLE9BQVYsQ0FBa0IsV0FBdUM7QUFBQSxZQUFwQ2tELElBQW9DLFNBQXBDQSxJQUFvQztBQUFBLFlBQTlCaUQsV0FBOEIsU0FBOUJBLFdBQThCO0FBQUEsWUFBakJuRCxVQUFpQixTQUFqQkEsVUFBaUI7O0FBQ3ZELFlBQUlFLFNBQVM1RSwwQkFBYixFQUF5QztBQUN2QzRILCtCQUFxQmpHLEdBQXJCLENBQXlCdEIsd0JBQXpCO0FBQ0Q7QUFDRCxZQUFJdUUsU0FBUzNFLHdCQUFiLEVBQXVDO0FBQ3JDLGNBQUl5RSxXQUFXb0QsTUFBWCxHQUFvQixDQUF4QixFQUEyQjtBQUN6QnBELHVCQUFXaEQsT0FBWCxDQUFtQm1DLGFBQWE7QUFDOUIsa0JBQUlBLFVBQVVrRSxRQUFkLEVBQXdCO0FBQ3RCSCxxQ0FBcUJqRyxHQUFyQixDQUF5QmtDLFVBQVVrRSxRQUFWLENBQW1CQyxJQUE1QztBQUNEO0FBQ0YsYUFKRDtBQUtEO0FBQ0QsY0FBSUgsV0FBSixFQUFpQjtBQUNmLGdCQUNFQSxZQUFZakQsSUFBWixLQUFxQnJFLG9CQUFyQixJQUNBc0gsWUFBWWpELElBQVosS0FBcUJwRSxpQkFEckIsSUFFQXFILFlBQVlqRCxJQUFaLEtBQXFCbEUsVUFIdkIsRUFJRTtBQUNBa0gsbUNBQXFCakcsR0FBckIsQ0FBeUJrRyxZQUFZSSxFQUFaLENBQWVELElBQXhDO0FBQ0Q7QUFDRCxnQkFBSUgsWUFBWWpELElBQVosS0FBcUJ0RSxvQkFBekIsRUFBK0M7QUFDN0N1SCwwQkFBWUssWUFBWixDQUF5QnhHLE9BQXpCLENBQWlDLFdBQVk7QUFBQSxvQkFBVHVHLEVBQVMsU0FBVEEsRUFBUzs7QUFDM0NMLHFDQUFxQmpHLEdBQXJCLENBQXlCc0csR0FBR0QsSUFBNUI7QUFDRCxlQUZEO0FBR0Q7QUFDRjtBQUNGO0FBQ0YsT0EzQkQ7O0FBNkJBO0FBQ0FoRyxjQUFRTixPQUFSLENBQWdCLENBQUNtQixLQUFELEVBQVFDLEdBQVIsS0FBZ0I7QUFDOUIsWUFBSThFLHFCQUFxQnRFLEdBQXJCLENBQXlCUixHQUF6QixDQUFKLEVBQW1DO0FBQ2pDNkUscUJBQVcvRSxHQUFYLENBQWVFLEdBQWYsRUFBb0JELEtBQXBCO0FBQ0Q7QUFDRixPQUpEOztBQU1BO0FBQ0ErRSwyQkFBcUJsRyxPQUFyQixDQUE2Qm9CLE9BQU87QUFDbEMsWUFBSSxDQUFDZCxRQUFRc0IsR0FBUixDQUFZUixHQUFaLENBQUwsRUFBdUI7QUFDckI2RSxxQkFBVy9FLEdBQVgsQ0FBZUUsR0FBZixFQUFvQixFQUFFQyxXQUFXLElBQUloQyxHQUFKLEVBQWIsRUFBcEI7QUFDRDtBQUNGLE9BSkQ7O0FBTUE7QUFDQSxVQUFJZSxZQUFZRSxRQUFRSSxHQUFSLENBQVlsQyxzQkFBWixDQUFoQjtBQUNBLFVBQUlpSCxtQkFBbUJuRixRQUFRSSxHQUFSLENBQVloQywwQkFBWixDQUF2Qjs7QUFFQSxVQUFJLE9BQU8rRyxnQkFBUCxLQUE0QixXQUFoQyxFQUE2QztBQUMzQ0EsMkJBQW1CLEVBQUVwRSxXQUFXLElBQUloQyxHQUFKLEVBQWIsRUFBbkI7QUFDRDs7QUFFRDRHLGlCQUFXL0UsR0FBWCxDQUFlMUMsc0JBQWYsRUFBdUM0QixTQUF2QztBQUNBNkYsaUJBQVcvRSxHQUFYLENBQWV4QywwQkFBZixFQUEyQytHLGdCQUEzQztBQUNBdEcsaUJBQVcrQixHQUFYLENBQWViLElBQWYsRUFBcUI0RixVQUFyQjtBQUNELEtBdEVEOztBQXdFQTs7Ozs7QUFLQSxVQUFNUSxvQkFBb0JsQixRQUFRO0FBQ2hDLFVBQUksQ0FBQ1QsYUFBTCxFQUFvQjtBQUNsQjtBQUNEOztBQUVELFVBQUk0QixpQkFBaUJ6SCxXQUFXeUIsR0FBWCxDQUFlTCxJQUFmLENBQXJCO0FBQ0EsVUFBSSxPQUFPcUcsY0FBUCxLQUEwQixXQUE5QixFQUEyQztBQUN6Q0EseUJBQWlCLElBQUl4SCxHQUFKLEVBQWpCO0FBQ0Q7O0FBRUQsWUFBTXlILHNCQUFzQixJQUFJdEgsR0FBSixFQUE1QjtBQUNBLFlBQU11SCxzQkFBc0IsSUFBSXZILEdBQUosRUFBNUI7O0FBRUEsWUFBTXdILGVBQWUsSUFBSXhILEdBQUosRUFBckI7QUFDQSxZQUFNeUgsZUFBZSxJQUFJekgsR0FBSixFQUFyQjs7QUFFQSxZQUFNMEgsb0JBQW9CLElBQUkxSCxHQUFKLEVBQTFCO0FBQ0EsWUFBTTJILG9CQUFvQixJQUFJM0gsR0FBSixFQUExQjs7QUFFQSxZQUFNNEgsYUFBYSxJQUFJL0gsR0FBSixFQUFuQjtBQUNBLFlBQU1nSSxhQUFhLElBQUloSSxHQUFKLEVBQW5CO0FBQ0F3SCxxQkFBZTFHLE9BQWYsQ0FBdUIsQ0FBQ21CLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNyQyxZQUFJRCxNQUFNUyxHQUFOLENBQVVwRCxzQkFBVixDQUFKLEVBQXVDO0FBQ3JDcUksdUJBQWE1RyxHQUFiLENBQWlCbUIsR0FBakI7QUFDRDtBQUNELFlBQUlELE1BQU1TLEdBQU4sQ0FBVWxELDBCQUFWLENBQUosRUFBMkM7QUFDekNpSSw4QkFBb0IxRyxHQUFwQixDQUF3Qm1CLEdBQXhCO0FBQ0Q7QUFDRCxZQUFJRCxNQUFNUyxHQUFOLENBQVVqRCx3QkFBVixDQUFKLEVBQXlDO0FBQ3ZDb0ksNEJBQWtCOUcsR0FBbEIsQ0FBc0JtQixHQUF0QjtBQUNEO0FBQ0RELGNBQU1uQixPQUFOLENBQWM2QixPQUFPO0FBQ25CLGNBQUlBLFFBQVFuRCwwQkFBUixJQUNBbUQsUUFBUWxELHdCQURaLEVBQ3NDO0FBQ2pDc0ksdUJBQVcvRixHQUFYLENBQWVXLEdBQWYsRUFBb0JULEdBQXBCO0FBQ0Q7QUFDTCxTQUxEO0FBTUQsT0FoQkQ7O0FBa0JBbUUsV0FBS00sSUFBTCxDQUFVN0YsT0FBVixDQUFrQm1ILFdBQVc7QUFDM0IsWUFBSUMsWUFBSjs7QUFFQTtBQUNBLFlBQUlELFFBQVFqRSxJQUFSLEtBQWlCM0Usd0JBQXJCLEVBQStDO0FBQzdDLGNBQUk0SSxRQUFRRSxNQUFaLEVBQW9CO0FBQ2xCRCwyQkFBZSx1QkFBUUQsUUFBUUUsTUFBUixDQUFlQyxHQUFmLENBQW1CQyxPQUFuQixDQUEyQixRQUEzQixFQUFxQyxFQUFyQyxDQUFSLEVBQWtENUgsT0FBbEQsQ0FBZjtBQUNBd0gsb0JBQVFuRSxVQUFSLENBQW1CaEQsT0FBbkIsQ0FBMkJtQyxhQUFhO0FBQ3RDLGtCQUFJbUUsSUFBSjtBQUNBLGtCQUFJbkUsVUFBVWtFLFFBQVYsQ0FBbUJDLElBQW5CLEtBQTRCdkgsT0FBaEMsRUFBeUM7QUFDdkN1SCx1QkFBTzNILHdCQUFQO0FBQ0QsZUFGRCxNQUVPO0FBQ0wySCx1QkFBT25FLFVBQVVULEtBQVYsQ0FBZ0I0RSxJQUF2QjtBQUNEO0FBQ0RZLHlCQUFXaEcsR0FBWCxDQUFlb0YsSUFBZixFQUFxQmMsWUFBckI7QUFDRCxhQVJEO0FBU0Q7QUFDRjs7QUFFRCxZQUFJRCxRQUFRakUsSUFBUixLQUFpQjFFLHNCQUFyQixFQUE2QztBQUMzQzRJLHlCQUFlLHVCQUFRRCxRQUFRRSxNQUFSLENBQWVDLEdBQWYsQ0FBbUJDLE9BQW5CLENBQTJCLFFBQTNCLEVBQXFDLEVBQXJDLENBQVIsRUFBa0Q1SCxPQUFsRCxDQUFmO0FBQ0FtSCx1QkFBYTdHLEdBQWIsQ0FBaUJtSCxZQUFqQjtBQUNEOztBQUVELFlBQUlELFFBQVFqRSxJQUFSLEtBQWlCekUsa0JBQXJCLEVBQXlDO0FBQ3ZDMkkseUJBQWUsdUJBQVFELFFBQVFFLE1BQVIsQ0FBZUMsR0FBZixDQUFtQkMsT0FBbkIsQ0FBMkIsUUFBM0IsRUFBcUMsRUFBckM