UNPKG

@neo-one/node-blockchain-esnext-cjs

Version:

NEO•ONE NEO blockchain implementation.

559 lines (558 loc) 85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const client_core_1 = require("@neo-one/client-core-esnext-cjs"); const utils_1 = require("@neo-one/utils-esnext-cjs"); const concat_1 = require("rxjs/internal/observable/concat"); const defer_1 = require("rxjs/internal/observable/defer"); const empty_1 = require("rxjs/internal/observable/empty"); const of_1 = require("rxjs/internal/observable/of"); const concatMap_1 = require("rxjs/internal/operators/concatMap"); function createGet({ tryGetTracked, readStorage }) { return async (key) => { const trackedChange = tryGetTracked(key); if (trackedChange !== undefined) { if (trackedChange.type === 'delete') { throw new Error('Not found'); } return trackedChange.value; } return readStorage().get(key); }; } function createTryGet({ tryGetTracked, readStorage }) { return async (key) => { const trackedChange = tryGetTracked(key); if (trackedChange !== undefined) { if (trackedChange.type === 'delete') { return undefined; } return trackedChange.value; } return readStorage().tryGet(key); }; } class BaseReadStorageCache { constructor(options) { this.readStorage = options.readStorage; this.name = options.name; this.createAddChange = options.createAddChange; this.createDeleteChange = options.createDeleteChange; this.onAdd = options.onAdd; this.mutableValues = {}; this.get = createGet({ readStorage: this.readStorage, tryGetTracked: this.tryGetTracked.bind(this) }); this.tryGet = createTryGet({ readStorage: this.readStorage, tryGetTracked: this.tryGetTracked.bind(this) }); } getChangeSet() { const createDeleteChange = this.createDeleteChange; return Object.values(this.mutableValues).map(value => { if (value.type === 'delete') { if (createDeleteChange === undefined) { throw new Error('Invalid delete'); } return { type: 'delete', change: createDeleteChange(value.key) }; } return { type: 'add', change: this.createAddChange(value.addValue) }; }); } tryGetTracked(_key) { throw new Error('Not Implemented'); } } exports.BaseReadStorageCache = BaseReadStorageCache; class ReadStorageCache extends BaseReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.getKeyString = options.getKeyString; } tryGetTracked(key) { return this.mutableValues[this.getKeyString(key)]; } } class ReadAllStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: () => ({ get: options.readAllStorage().get, tryGet: options.readAllStorage().tryGet }), name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.readAllStorage = options.readAllStorage; this.getKeyFromValue = options.getKeyFromValue; this.all$ = concat_1.concat(defer_1.defer(() => this.readAllStorage().all$.pipe(concatMap_1.concatMap(value => { const trackedChange = this.tryGetTracked(this.getKeyFromValue(value)); if (trackedChange !== undefined) { return empty_1.EMPTY; } return of_1.of(value); }))), defer_1.defer(() => of_1.of(...Object.values(this.mutableValues).map(value => value.type === 'add' ? value.value : undefined).filter(utils_1.utils.notNull)))); } } class ReadGetAllStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: () => ({ get: options.readGetAllStorage().get, tryGet: options.readGetAllStorage().tryGet }), name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.readGetAllStorage = options.readGetAllStorage; this.getKeyFromValue = options.getKeyFromValue; this.matchesPartialKey = options.matchesPartialKey; this.getAll$ = (key) => concat_1.concat(defer_1.defer(() => this.readGetAllStorage().getAll$(key).pipe(concatMap_1.concatMap(value => { const trackedChange = this.tryGetTracked(this.getKeyFromValue(value)); if (trackedChange !== undefined) { return empty_1.EMPTY; } return of_1.of(value); }))), defer_1.defer(() => of_1.of(...Object.values(this.mutableValues).map(value => value.type === 'add' && this.matchesPartialKey(value.value, key) ? value.value : undefined).filter(utils_1.utils.notNull)))); } } function createAdd({ cache, getKeyFromValue, getKeyString }) { return async (value, force) => { const key = getKeyFromValue(value); if (!force) { const currentValue = await cache.tryGet(key); if (currentValue !== undefined) { throw new Error(`Attempted to add an already existing object for key ` + `${cache.name}:${getKeyString(key)}.`); } } if (cache.onAdd !== undefined) { await cache.onAdd(value); } // tslint:disable-next-line no-object-mutation cache.mutableValues[cache.getKeyString(key)] = { type: 'add', addValue: value, value }; }; } function createUpdate({ cache, update: updateFunc, getKeyFromValue }) { return async (value, update) => { const key = getKeyFromValue(value); const updatedValue = updateFunc(value, update); // tslint:disable-next-line no-object-mutation cache.mutableValues[cache.getKeyString(key)] = { type: 'add', addValue: updatedValue, value: updatedValue }; return updatedValue; }; } function createDelete({ cache }) { return async (key) => { // tslint:disable-next-line no-object-mutation cache.mutableValues[cache.getKeyString(key)] = { type: 'delete', key }; }; } class ReadAddUpdateDeleteStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.update = createUpdate({ cache: this, update: options.update, getKeyFromValue: options.getKeyFromValue }); this.delete = createDelete({ cache: this }); } } exports.ReadAddUpdateDeleteStorageCache = ReadAddUpdateDeleteStorageCache; class ReadAddUpdateStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.update = createUpdate({ cache: this, update: options.update, getKeyFromValue: options.getKeyFromValue }); } } exports.ReadAddUpdateStorageCache = ReadAddUpdateStorageCache; class ReadAddDeleteStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.delete = createDelete({ cache: this }); } } exports.ReadAddDeleteStorageCache = ReadAddDeleteStorageCache; class ReadAddStorageCache extends ReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); } } exports.ReadAddStorageCache = ReadAddStorageCache; class ReadGetAllAddDeleteStorageCache extends ReadGetAllStorageCache { constructor(options) { super({ readGetAllStorage: options.readGetAllStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd, getKeyFromValue: options.getKeyFromValue, matchesPartialKey: options.matchesPartialKey }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.delete = createDelete({ cache: this }); } } exports.ReadGetAllAddDeleteStorageCache = ReadGetAllAddDeleteStorageCache; class ReadGetAllAddUpdateDeleteStorageCache extends ReadGetAllStorageCache { constructor(options) { super({ readGetAllStorage: options.readGetAllStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd, getKeyFromValue: options.getKeyFromValue, matchesPartialKey: options.matchesPartialKey }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.update = createUpdate({ cache: this, update: options.update, getKeyFromValue: options.getKeyFromValue }); this.delete = createDelete({ cache: this }); } } exports.ReadGetAllAddUpdateDeleteStorageCache = ReadGetAllAddUpdateDeleteStorageCache; class ReadGetAllAddStorageCache extends ReadGetAllStorageCache { constructor(options) { super({ readGetAllStorage: options.readGetAllStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd, getKeyFromValue: options.getKeyFromValue, matchesPartialKey: options.matchesPartialKey }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); } } exports.ReadGetAllAddStorageCache = ReadGetAllAddStorageCache; class ReadAllAddUpdateDeleteStorageCache extends ReadAllStorageCache { constructor(options) { super({ readAllStorage: options.readAllStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd, getKeyFromValue: options.getKeyFromValue }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); this.update = createUpdate({ cache: this, update: options.update, getKeyFromValue: options.getKeyFromValue }); this.delete = createDelete({ cache: this }); } } exports.ReadAllAddUpdateDeleteStorageCache = ReadAllAddUpdateDeleteStorageCache; class ReadAllAddStorageCache extends ReadAllStorageCache { constructor(options) { super({ readAllStorage: options.readAllStorage, name: options.name, getKeyString: options.getKeyString, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd, getKeyFromValue: options.getKeyFromValue }); this.add = createAdd({ cache: this, getKeyFromValue: options.getKeyFromValue, getKeyString: options.getKeyString }); } } exports.ReadAllAddStorageCache = ReadAllAddStorageCache; class BlockLikeStorageCache extends BaseReadStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, createAddChange: options.createAddChange }); this.mutableIndexValues = {}; } async add(value, force) { if (!force) { const currentValue = await this.tryGet({ hashOrIndex: value.index }); if (currentValue !== undefined) { throw new Error('Attempted to add an already existing object.'); } } const addValue = { type: 'add', addValue: value, value }; this.mutableValues[client_core_1.common.uInt256ToString(value.hash)] = addValue; this.mutableIndexValues[`${value.index}`] = addValue; } tryGetTracked(key) { if (typeof key.hashOrIndex !== 'number') { return this.mutableValues[client_core_1.common.uInt256ToString(key.hashOrIndex)]; } return this.mutableIndexValues[`${key.hashOrIndex}`]; } } exports.BlockLikeStorageCache = BlockLikeStorageCache; const getOutputValueKeyString = (key) => `${client_core_1.common.uInt256ToHex(key.hash)}:${key.index}`; class OutputStorageCache extends ReadStorageCache { constructor(readStorage) { super({ readStorage, name: 'output', getKeyString: getOutputValueKeyString, createAddChange: (value) => ({ type: 'output', value }) }); this.add = async (value, force) => { const key = { hash: value.hash, index: value.index }; if (!force) { const currentValue = await this.tryGet(key); if (currentValue !== undefined) { throw new Error(`Attempted to add an already existing object for key ` + `${this.name}:${this.getKeyString(key)}.`); } } this.mutableValues[this.getKeyString(key)] = { type: 'add', addValue: value, value: value.output }; }; } } exports.OutputStorageCache = OutputStorageCache; function createGetMetadata({ tryGetTracked, readStorage }) { return async () => { const trackedChange = tryGetTracked(); if (trackedChange !== undefined) { if (trackedChange.type === 'delete') { throw new Error('Not found'); } return trackedChange.value; } return readStorage().get(); }; } function createTryGetMetadata({ tryGetTracked, readStorage }) { return async () => { const trackedChange = tryGetTracked(); if (trackedChange !== undefined) { if (trackedChange.type === 'delete') { return undefined; } return trackedChange.value; } return readStorage().tryGet(); }; } class BaseReadMetadataStorageCache { constructor(options) { this.readStorage = options.readStorage; this.name = options.name; this.createAddChange = options.createAddChange; this.createDeleteChange = options.createDeleteChange; this.onAdd = options.onAdd; this.get = createGetMetadata({ readStorage: this.readStorage, tryGetTracked: this.tryGetTracked.bind(this) }); this.tryGet = createTryGetMetadata({ readStorage: this.readStorage, tryGetTracked: this.tryGetTracked.bind(this) }); } getChangeSet() { const createDeleteChange = this.createDeleteChange; const value = this.mutableValue; if (value === undefined) { return []; } if (value.type === 'delete') { if (createDeleteChange === undefined) { throw new Error('Invalid delete'); } return [{ type: 'delete', change: createDeleteChange() }]; } return [{ type: 'add', change: this.createAddChange(value.addValue) }]; } tryGetTracked() { return this.mutableValue; } } exports.BaseReadMetadataStorageCache = BaseReadMetadataStorageCache; class ReadMetadataStorageCache extends BaseReadMetadataStorageCache { } function createAddMetadata({ cache }) { return async (value) => { if (cache.onAdd !== undefined) { await cache.onAdd(value); } // tslint:disable-next-line no-object-mutation cache.mutableValue = { type: 'add', addValue: value, value }; }; } function createUpdateMetadata({ cache, update: updateFunc }) { return async (value, update) => { const updatedValue = updateFunc(value, update); // tslint:disable-next-line no-object-mutation cache.mutableValue = { type: 'add', addValue: updatedValue, value: updatedValue }; return updatedValue; }; } class ReadAddUpdateMetadataStorageCache extends ReadMetadataStorageCache { constructor(options) { super({ readStorage: options.readStorage, name: options.name, createAddChange: options.createAddChange, createDeleteChange: options.createDeleteChange, onAdd: options.onAdd }); this.add = createAddMetadata({ cache: this }); this.update = createUpdateMetadata({ cache: this, update: options.update }); } } exports.ReadAddUpdateMetadataStorageCache = ReadAddUpdateMetadataStorageCache; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlN0b3JhZ2VDYWNoZS50cyJdLCJuYW1lcyI6WyJjcmVhdGVHZXQiLCJ0cnlHZXRUcmFja2VkIiwicmVhZFN0b3JhZ2UiLCJrZXkiLCJ0cmFja2VkQ2hhbmdlIiwidW5kZWZpbmVkIiwidHlwZSIsIkVycm9yIiwidmFsdWUiLCJnZXQiLCJjcmVhdGVUcnlHZXQiLCJ0cnlHZXQiLCJCYXNlUmVhZFN0b3JhZ2VDYWNoZSIsIm9wdGlvbnMiLCJuYW1lIiwiY3JlYXRlQWRkQ2hhbmdlIiwiY3JlYXRlRGVsZXRlQ2hhbmdlIiwib25BZGQiLCJtdXRhYmxlVmFsdWVzIiwiYmluZCIsImdldENoYW5nZVNldCIsIk9iamVjdCIsInZhbHVlcyIsIm1hcCIsImNoYW5nZSIsImFkZFZhbHVlIiwiX2tleSIsIlJlYWRTdG9yYWdlQ2FjaGUiLCJnZXRLZXlTdHJpbmciLCJSZWFkQWxsU3RvcmFnZUNhY2hlIiwicmVhZEFsbFN0b3JhZ2UiLCJnZXRLZXlGcm9tVmFsdWUiLCJhbGwkIiwiY29uY2F0IiwiZGVmZXIiLCJwaXBlIiwiY29uY2F0TWFwIiwiRU1QVFkiLCJfb2YiLCJmaWx0ZXIiLCJjb21tb25VdGlscyIsIm5vdE51bGwiLCJSZWFkR2V0QWxsU3RvcmFnZUNhY2hlIiwicmVhZEdldEFsbFN0b3JhZ2UiLCJtYXRjaGVzUGFydGlhbEtleSIsImdldEFsbCQiLCJjcmVhdGVBZGQiLCJjYWNoZSIsImZvcmNlIiwiY3VycmVudFZhbHVlIiwiY3JlYXRlVXBkYXRlIiwidXBkYXRlIiwidXBkYXRlRnVuYyIsInVwZGF0ZWRWYWx1ZSIsImNyZWF0ZURlbGV0ZSIsIlJlYWRBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGUiLCJhZGQiLCJkZWxldGUiLCJSZWFkQWRkVXBkYXRlU3RvcmFnZUNhY2hlIiwiUmVhZEFkZERlbGV0ZVN0b3JhZ2VDYWNoZSIsIlJlYWRBZGRTdG9yYWdlQ2FjaGUiLCJSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlIiwiUmVhZEdldEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZSIsIlJlYWRHZXRBbGxBZGRTdG9yYWdlQ2FjaGUiLCJSZWFkQWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlIiwiUmVhZEFsbEFkZFN0b3JhZ2VDYWNoZSIsIkJsb2NrTGlrZVN0b3JhZ2VDYWNoZSIsIm11dGFibGVJbmRleFZhbHVlcyIsImhhc2hPckluZGV4IiwiaW5kZXgiLCJjb21tb24iLCJ1SW50MjU2VG9TdHJpbmciLCJoYXNoIiwiZ2V0T3V0cHV0VmFsdWVLZXlTdHJpbmciLCJ1SW50MjU2VG9IZXgiLCJPdXRwdXRTdG9yYWdlQ2FjaGUiLCJvdXRwdXQiLCJjcmVhdGVHZXRNZXRhZGF0YSIsImNyZWF0ZVRyeUdldE1ldGFkYXRhIiwiQmFzZVJlYWRNZXRhZGF0YVN0b3JhZ2VDYWNoZSIsIm11dGFibGVWYWx1ZSIsIlJlYWRNZXRhZGF0YVN0b3JhZ2VDYWNoZSIsImNyZWF0ZUFkZE1ldGFkYXRhIiwiY3JlYXRlVXBkYXRlTWV0YWRhdGEiLCJSZWFkQWRkVXBkYXRlTWV0YWRhdGFTdG9yYWdlQ2FjaGUiXSwibWFwcGluZ3MiOiI7O0FBQUEsc0RBQUE7QUFXQSwwQ0FBQTtBQVJBLDREQUF5RDtBQUN6RCwwREFBdUQ7QUFDdkQsMERBQXVEO0FBRXZELG9EQUF3RDtBQUN4RCxpRUFBOEQ7QUFZOUQsU0FBU0EsU0FBUyxDQUFhLEVBQzdCQyxhQUQ2QixFQUU3QkMsV0FBQUEsRUFGRjtJQVFFLE9BQU8sS0FBQSxFQUFPQyxHQUFQLEVBQUEsRUFBQTtRQUNMLE1BQU1DLGFBQUFBLEdBQWdCSCxhQUFBQSxDQUFjRSxHQUFkLENBQXRCLENBQUE7UUFDQSxJQUFJQyxhQUFBQSxLQUFrQkMsU0FBdEIsRUFBaUM7WUFDL0IsSUFBSUQsYUFBQUEsQ0FBY0UsSUFBZCxLQUF1QixRQUEzQixFQUFxQztnQkFDbkMsTUFBTSxJQUFJQyxLQUFKLENBQVUsV0FBVixDQUFOLENBQUE7YUFDRDtZQUVELE9BQU9ILGFBQUFBLENBQWNJLEtBQXJCLENBQUE7U0FDRDtRQUVELE9BQU9OLFdBQUFBLEVBQUFBLENBQWNPLEdBQWQsQ0FBa0JOLEdBQWxCLENBQVAsQ0FBQTtJQUNELENBWEQsQ0FBQTtBQVlELENBQUE7QUFFRCxTQUFTTyxZQUFZLENBQWEsRUFDaENULGFBRGdDLEVBRWhDQyxXQUFBQSxFQUZGO0lBUUUsT0FBTyxLQUFBLEVBQU9DLEdBQVAsRUFBQSxFQUFBO1FBQ0wsTUFBTUMsYUFBQUEsR0FBZ0JILGFBQUFBLENBQWNFLEdBQWQsQ0FBdEIsQ0FBQTtRQUNBLElBQUlDLGFBQUFBLEtBQWtCQyxTQUF0QixFQUFpQztZQUMvQixJQUFJRCxhQUFBQSxDQUFjRSxJQUFkLEtBQXVCLFFBQTNCLEVBQXFDO2dCQUNuQyxPQUFPRCxTQUFQLENBQUE7YUFDRDtZQUVELE9BQU9ELGFBQUFBLENBQWNJLEtBQXJCLENBQUE7U0FDRDtRQUVELE9BQU9OLFdBQUFBLEVBQUFBLENBQWNTLE1BQWQsQ0FBcUJSLEdBQXJCLENBQVAsQ0FBQTtJQUNELENBWEQsQ0FBQTtBQVlELENBQUE7QUFVRCxNQUFhUyxvQkFBb0I7SUFXL0IsWUFBbUJDLE9BQW5CO1FBQ0UsSUFBQSxDQUFLWCxXQUFMLEdBQW1CVyxPQUFBQSxDQUFRWCxXQUEzQixDQUFBO1FBQ0EsSUFBQSxDQUFLWSxJQUFMLEdBQVlELE9BQUFBLENBQVFDLElBQXBCLENBQUE7UUFDQSxJQUFBLENBQUtDLGVBQUwsR0FBdUJGLE9BQUFBLENBQVFFLGVBQS9CLENBQUE7UUFDQSxJQUFBLENBQUtDLGtCQUFMLEdBQTBCSCxPQUFBQSxDQUFRRyxrQkFBbEMsQ0FBQTtRQUNBLElBQUEsQ0FBS0MsS0FBTCxHQUFhSixPQUFBQSxDQUFRSSxLQUFyQixDQUFBO1FBQ0EsSUFBQSxDQUFLQyxhQUFMLEdBQXFCLEVBQXJCLENBQUE7UUFFQSxJQUFBLENBQUtULEdBQUwsR0FBV1QsU0FBQUEsQ0FBVTtZQUNuQkUsV0FBQUEsRUFBYSxJQUFBLENBQUtBLFdBREM7WUFFbkJELGFBQUFBLEVBQWUsSUFBQSxDQUFLQSxhQUFMLENBQW1Ca0IsSUFBbkIsQ0FBd0IsSUFBeEIsQ0FBQTtTQUZOLENBQVgsQ0FBQTtRQUtBLElBQUEsQ0FBS1IsTUFBTCxHQUFjRCxZQUFBQSxDQUFhO1lBQ3pCUixXQUFBQSxFQUFhLElBQUEsQ0FBS0EsV0FETztZQUV6QkQsYUFBQUEsRUFBZSxJQUFBLENBQUtBLGFBQUwsQ0FBbUJrQixJQUFuQixDQUF3QixJQUF4QixDQUFBO1NBRkgsQ0FBZCxDQUFBO0lBSUQsQ0FBQTtJQUVNQyxZQUFQO1FBQ0UsTUFBTUosa0JBQUFBLEdBQXFCLElBQUEsQ0FBS0Esa0JBQWhDLENBQUE7UUFFQSxPQUFPSyxNQUFBQSxDQUFPQyxNQUFQLENBQWMsSUFBQSxDQUFLSixhQUFuQixDQUFBLENBQWtDSyxHQUFHLENBQVVmLEtBQUQsQ0FBQSxFQUFBO1lBQ25ELElBQUlBLEtBQUFBLENBQU1GLElBQU4sS0FBZSxRQUFuQixFQUE2QjtnQkFDM0IsSUFBSVUsa0JBQUFBLEtBQXVCWCxTQUEzQixFQUFzQztvQkFDcEMsTUFBTSxJQUFJRSxLQUFKLENBQVUsZ0JBQVYsQ0FBTixDQUFBO2lCQUNEO2dCQUVELE9BQU87b0JBQUVELElBQUFBLEVBQU0sUUFBUjtvQkFBa0JrQixNQUFBQSxFQUFRUixrQkFBQUEsQ0FBbUJSLEtBQUFBLENBQU1MLEdBQXpCLENBQUE7aUJBQWpDLENBQUE7YUFDRDtZQUVELE9BQU87Z0JBQUVHLElBQUFBLEVBQU0sS0FBUjtnQkFBZWtCLE1BQUFBLEVBQVEsSUFBQSxDQUFLVCxlQUFMLENBQXFCUCxLQUFBQSxDQUFNaUIsUUFBM0IsQ0FBQTthQUE5QixDQUFBO1FBQ0QsQ0FWTSxDQUFQLENBQUE7SUFXRCxDQUFBO0lBRVN4QixhQUFWLENBQXdCeUIsSUFBeEI7UUFDRSxNQUFNLElBQUluQixLQUFKLENBQVUsaUJBQVYsQ0FBTixDQUFBO0lBQ0QsQ0FBQTtDQWhEcUQ7QUFBeEQsb0RBQXdEO0FBdUR4RCxNQUFNb0IsZ0JBQU4sU0FBcURmLG9CQUFyRDtJQUdFLFlBQW1CQyxPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKWCxXQUFBQSxFQUFhVyxPQUFBQSxDQUFRWCxXQURqQjtZQUVKWSxJQUFBQSxFQUFNRCxPQUFBQSxDQUFRQyxJQUZWO1lBR0pDLGVBQUFBLEVBQWlCRixPQUFBQSxDQUFRRSxlQUhyQjtZQUlKQyxrQkFBQUEsRUFBb0JILE9BQUFBLENBQVFHLGtCQUp4QjtZQUtKQyxLQUFBQSxFQUFPSixPQUFBQSxDQUFRSSxLQUFBQTtTQUxqQixDQUFBLENBQUE7UUFRQSxJQUFBLENBQUtXLFlBQUwsR0FBb0JmLE9BQUFBLENBQVFlLFlBQTVCLENBQUE7SUFDRCxDQUFBO0lBRVMzQixhQUFWLENBQXdCRSxHQUF4QjtRQUNFLE9BQU8sSUFBQSxDQUFLZSxhQUFMLENBQW1CLElBQUEsQ0FBS1UsWUFBTCxDQUFrQnpCLEdBQWxCLENBQW5CLENBQVAsQ0FBQTtJQUNELENBQUE7Q0FqQjZGO0FBOEJoRyxNQUFNMEIsbUJBQU4sU0FBOENGLGdCQUE5QztJQUtFLFlBQW1CZCxPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKWCxXQUFBQSxFQUFhLEdBQUEsRUFBQSxDQUFBLENBQU87Z0JBQ2xCTyxHQUFBQSxFQUFLSSxPQUFBQSxDQUFRaUIsY0FBUixFQUFBLENBQXlCckIsR0FEWjtnQkFFbEJFLE1BQUFBLEVBQVFFLE9BQUFBLENBQVFpQixjQUFSLEVBQUEsQ0FBeUJuQixNQUFBQTthQUZ0QixDQURUO1lBS0pHLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBTFY7WUFNSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFObEI7WUFPSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBUHJCO1lBUUpDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBUnhCO1lBU0pDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBQUFBO1NBVGpCLENBQUEsQ0FBQTtRQVlBLElBQUEsQ0FBS2EsY0FBTCxHQUFzQmpCLE9BQUFBLENBQVFpQixjQUE5QixDQUFBO1FBQ0EsSUFBQSxDQUFLQyxlQUFMLEdBQXVCbEIsT0FBQUEsQ0FBUWtCLGVBQS9CLENBQUE7UUFFQSxJQUFBLENBQUtDLElBQUwsR0FBWUMsZUFBQUEsQ0FDVkMsYUFBQUEsQ0FBTSxHQUFBLEVBQUEsQ0FDSixJQUFBLENBQUtKLGNBQUwsRUFBQSxDQUFzQkUsSUFBdEIsQ0FBMkJHLElBQTNCLENBQ0VDLHFCQUFBQSxDQUFXNUIsS0FBRCxDQUFBLEVBQUE7WUFDUixNQUFNSixhQUFBQSxHQUFnQixJQUFBLENBQUtILGFBQUwsQ0FBbUIsSUFBQSxDQUFLOEIsZUFBTCxDQUFxQnZCLEtBQXJCLENBQW5CLENBQXRCLENBQUE7WUFFQSxJQUFJSixhQUFBQSxLQUFrQkMsU0FBdEIsRUFBaUM7Z0JBQy9CLE9BQU9nQyxhQUFQLENBQUE7YUFDRDtZQUVELE9BQU9DLE9BQUFBLENBQUk5QixLQUFKLENBQVAsQ0FBQTtRQUNELENBUkQsQ0FERixDQURGLENBRFUsRUFjVjBCLGFBQUFBLENBQU0sR0FBQSxFQUFBLENBQ0pJLE9BQUFBLENBQ0UsR0FBR2pCLE1BQUFBLENBQU9DLE1BQVAsQ0FBYyxJQUFBLENBQUtKLGFBQW5CLENBQUEsQ0FDQUssR0FEQSxDQUNLZixLQUFELENBQUEsRUFBQSxDQUFZQSxLQUFBQSxDQUFNRixJQUFOLEtBQWUsS0FBZixDQUFBLENBQUEsQ0FBdUJFLEtBQUFBLENBQU1BLEtBQTdCLENBQUEsQ0FBQSxDQUFxQ0gsU0FEckQsQ0FBQSxDQUVBa0MsTUFGQSxDQUVPQyxhQUFBQSxDQUFZQyxPQUZuQixDQURMLENBREYsQ0FkVSxDQUFaLENBQUE7SUFzQkQsQ0FBQTtDQTNDK0U7QUF5RGxGLE1BQU1DLHNCQUFOLFNBQTZEZixnQkFBN0Q7SUFNRSxZQUFtQmQsT0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSlgsV0FBQUEsRUFBYSxHQUFBLEVBQUEsQ0FBQSxDQUFPO2dCQUNsQk8sR0FBQUEsRUFBS0ksT0FBQUEsQ0FBUThCLGlCQUFSLEVBQUEsQ0FBNEJsQyxHQURmO2dCQUVsQkUsTUFBQUEsRUFBUUUsT0FBQUEsQ0FBUThCLGlCQUFSLEVBQUEsQ0FBNEJoQyxNQUFBQTthQUZ6QixDQURUO1lBS0pHLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBTFY7WUFNSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFObEI7WUFPSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBUHJCO1lBUUpDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBUnhCO1lBU0pDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBQUFBO1NBVGpCLENBQUEsQ0FBQTtRQVlBLElBQUEsQ0FBSzBCLGlCQUFMLEdBQXlCOUIsT0FBQUEsQ0FBUThCLGlCQUFqQyxDQUFBO1FBQ0EsSUFBQSxDQUFLWixlQUFMLEdBQXVCbEIsT0FBQUEsQ0FBUWtCLGVBQS9CLENBQUE7UUFDQSxJQUFBLENBQUthLGlCQUFMLEdBQXlCL0IsT0FBQUEsQ0FBUStCLGlCQUFqQyxDQUFBO1FBRUEsSUFBQSxDQUFLQyxPQUFMLEdBQWUsQ0FBQzFDLEdBQUQsRUFBQSxFQUFBLENBQ2I4QixlQUFBQSxDQUNFQyxhQUFBQSxDQUFNLEdBQUEsRUFBQSxDQUNKLElBQUEsQ0FBS1MsaUJBQUwsRUFBQSxDQUNHRSxPQURILENBQ1cxQyxHQURYLENBQUEsQ0FFR2dDLElBRkgsQ0FHSUMscUJBQUFBLENBQVc1QixLQUFELENBQUEsRUFBQTtZQUNSLE1BQU1KLGFBQUFBLEdBQWdCLElBQUEsQ0FBS0gsYUFBTCxDQUFtQixJQUFBLENBQUs4QixlQUFMLENBQXFCdkIsS0FBckIsQ0FBbkIsQ0FBdEIsQ0FBQTtZQUVBLElBQUlKLGFBQUFBLEtBQWtCQyxTQUF0QixFQUFpQztnQkFDL0IsT0FBT2dDLGFBQVAsQ0FBQTthQUNEO1lBRUQsT0FBT0MsT0FBQUEsQ0FBSTlCLEtBQUosQ0FBUCxDQUFBO1FBQ0QsQ0FSRCxDQUhKLENBREYsQ0FERixFQWdCRTBCLGFBQUFBLENBQU0sR0FBQSxFQUFBLENBQ0pJLE9BQUFBLENBQ0UsR0FBR2pCLE1BQUFBLENBQU9DLE1BQVAsQ0FBYyxJQUFBLENBQUtKLGFBQW5CLENBQUEsQ0FDQUssR0FEQSxDQUVFZixLQUFELENBQUEsRUFBQSxDQUFZQSxLQUFBQSxDQUFNRixJQUFOLEtBQWUsS0FBZixJQUF3QixJQUFBLENBQUtzQyxpQkFBTCxDQUF1QnBDLEtBQUFBLENBQU1BLEtBQTdCLEVBQW9DTCxHQUFwQyxDQUF4QixDQUFBLENBQUEsQ0FBbUVLLEtBQUFBLENBQU1BLEtBQXpFLENBQUEsQ0FBQSxDQUFpRkgsU0FGOUYsQ0FBQSxDQUlBa0MsTUFKQSxDQUlPQyxhQUFBQSxDQUFZQyxPQUpuQixDQURMLENBREYsQ0FoQkYsQ0FERixDQUFBO0lBMkJELENBQUE7Q0FsRDhGO0FBc0RqRyxTQUFTSyxTQUFTLENBQWEsRUFDN0JDLEtBRDZCLEVBRTdCaEIsZUFGNkIsRUFHN0JILFlBQUFBLEVBSEY7SUFTRSxPQUFPLEtBQUEsRUFBT3BCLEtBQVAsRUFBcUJ3QyxLQUFyQixFQUFBLEVBQUE7UUFDTCxNQUFNN0MsR0FBQUEsR0FBTTRCLGVBQUFBLENBQWdCdkIsS0FBaEIsQ0FBWixDQUFBO1FBRUEsSUFBSSxDQUFDd0MsS0FBTCxFQUFZO1lBQ1YsTUFBTUMsWUFBQUEsR0FBZSxNQUFNRixLQUFBQSxDQUFNcEMsTUFBTixDQUFhUixHQUFiLENBQTNCLENBQUE7WUFDQSxJQUFJOEMsWUFBQUEsS0FBaUI1QyxTQUFyQixFQUFnQztnQkFDOUIsTUFBTSxJQUFJRSxLQUFKLENBQVcsc0RBQUQsR0FBMEQsR0FBRXdDLEtBQUFBLENBQU1qQyxJQUFLLElBQUdjLFlBQUFBLENBQWF6QixHQUFiLENBQWtCLEdBQXRHLENBQU4sQ0FBQTthQUNEO1NBQ0Y7UUFFRCxJQUFJNEMsS0FBQUEsQ0FBTTlCLEtBQU4sS0FBZ0JaLFNBQXBCLEVBQStCO1lBQzdCLE1BQU0wQyxLQUFBQSxDQUFNOUIsS0FBTixDQUFZVCxLQUFaLENBQU4sQ0FBQTtTQVhrRCxDQWNwRCw4Q0FBQTtRQUNBdUMsS0FBQUEsQ0FBTTdCLGFBQU4sQ0FBb0I2QixLQUFBQSxDQUFNbkIsWUFBTixDQUFtQnpCLEdBQW5CLENBQXBCLENBQUEsR0FBK0M7WUFDN0NHLElBQUFBLEVBQU0sS0FEdUM7WUFFN0NtQixRQUFBQSxFQUFVakIsS0FGbUM7WUFHN0NBLEtBQUFBO1NBSEYsQ0FBQTtJQUtELENBcEJELENBQUE7QUFxQkQsQ0FBQTtBQUdELFNBQVMwQyxZQUFZLENBQXFCLEVBQ3hDSCxLQUR3QyxFQUV4Q0ksTUFBQUEsRUFBUUMsVUFGZ0MsRUFHeENyQixlQUFBQSxFQUhGO0lBU0UsT0FBTyxLQUFBLEVBQU92QixLQUFQLEVBQXFCMkMsTUFBckIsRUFBQSxFQUFBO1FBQ0wsTUFBTWhELEdBQUFBLEdBQU00QixlQUFBQSxDQUFnQnZCLEtBQWhCLENBQVosQ0FBQTtRQUVBLE1BQU02QyxZQUFBQSxHQUFlRCxVQUFBQSxDQUFXNUMsS0FBWCxFQUFrQjJDLE1BQWxCLENBQXJCLENBSDZELENBSTdELDhDQUFBO1FBQ0FKLEtBQUFBLENBQU03QixhQUFOLENBQW9CNkIsS0FBQUEsQ0FBTW5CLFlBQU4sQ0FBbUJ6QixHQUFuQixDQUFwQixDQUFBLEdBQStDO1lBQzdDRyxJQUFBQSxFQUFNLEtBRHVDO1lBRTdDbUIsUUFBQUEsRUFBVTRCLFlBRm1DO1lBRzdDN0MsS0FBQUEsRUFBTzZDLFlBQUFBO1NBSFQsQ0FBQTtRQU1BLE9BQU9BLFlBQVAsQ0FBQTtJQUNELENBWkQsQ0FBQTtBQWFELENBQUE7QUFJRCxTQUFTQyxZQUFZLENBQU0sRUFBRVAsS0FBQUEsRUFBN0I7SUFDRSxPQUFPLEtBQUEsRUFBTzVDLEdBQVAsRUFBQSxFQUFBO1FBQ0wsOENBQUE7UUFDQTRDLEtBQUFBLENBQU03QixhQUFOLENBQW9CNkIsS0FBQUEsQ0FBTW5CLFlBQU4sQ0FBbUJ6QixHQUFuQixDQUFwQixDQUFBLEdBQStDO1lBQUVHLElBQUFBLEVBQU0sUUFBUjtZQUFrQkgsR0FBQUE7U0FBakUsQ0FBQTtJQUNELENBSEQsQ0FBQTtBQUlELENBQUE7QUFRRCxNQUFhb0QsK0JBQU4sU0FBa0U1QixnQkFBbEU7SUFLTCxZQUFtQmQsT0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSlgsV0FBQUEsRUFBYVcsT0FBQUEsQ0FBUVgsV0FEakI7WUFFSlksSUFBQUEsRUFBTUQsT0FBQUEsQ0FBUUMsSUFGVjtZQUdKYyxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUhsQjtZQUlKYixlQUFBQSxFQUFpQkYsT0FBQUEsQ0FBUUUsZUFKckI7WUFLSkMsa0JBQUFBLEVBQW9CSCxPQUFBQSxDQUFRRyxrQkFMeEI7WUFNSkMsS0FBQUEsRUFBT0osT0FBQUEsQ0FBUUksS0FBQUE7U0FOakIsQ0FBQSxDQUFBO1FBU0EsSUFBQSxDQUFLdUMsR0FBTCxHQUFXVixTQUFBQSxDQUFVO1lBQ25CQyxLQUFBQSxFQUFPLElBRFk7WUFFbkJoQixlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQUZOO1lBR25CSCxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUFBQTtTQUhiLENBQVgsQ0FBQTtRQU1BLElBQUEsQ0FBS3VCLE1BQUwsR0FBY0QsWUFBQUEsQ0FBYTtZQUN6QkgsS0FBQUEsRUFBTyxJQURrQjtZQUV6QkksTUFBQUEsRUFBUXRDLE9BQUFBLENBQVFzQyxNQUZTO1lBR3pCcEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFBQUE7U0FIYixDQUFkLENBQUE7UUFNQSxJQUFBLENBQUswQixNQUFMLEdBQWNILFlBQUFBLENBQWE7WUFBRVAsS0FBQUEsRUFBTyxJQUFBO1NBQXRCLENBQWQsQ0FBQTtJQUNELENBQUE7Q0E1QjBHO0FBQTdHLDBFQUE2RztBQW9DN0csTUFBYVcseUJBQU4sU0FBNEQvQixnQkFBNUQ7SUFJTCxZQUFtQmQsT0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSlgsV0FBQUEsRUFBYVcsT0FBQUEsQ0FBUVgsV0FEakI7WUFFSlksSUFBQUEsRUFBTUQsT0FBQUEsQ0FBUUMsSUFGVjtZQUdKYyxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUhsQjtZQUlKYixlQUFBQSxFQUFpQkYsT0FBQUEsQ0FBUUUsZUFKckI7WUFLSkMsa0JBQUFBLEVBQW9CSCxPQUFBQSxDQUFRRyxrQkFMeEI7WUFNSkMsS0FBQUEsRUFBT0osT0FBQUEsQ0FBUUksS0FBQUE7U0FOakIsQ0FBQSxDQUFBO1FBU0EsSUFBQSxDQUFLdUMsR0FBTCxHQUFXVixTQUFBQSxDQUFVO1lBQ25CQyxLQUFBQSxFQUFPLElBRFk7WUFFbkJoQixlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQUZOO1lBR25CSCxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUFBQTtTQUhiLENBQVgsQ0FBQTtRQU1BLElBQUEsQ0FBS3VCLE1BQUwsR0FBY0QsWUFBQUEsQ0FBYTtZQUN6QkgsS0FBQUEsRUFBTyxJQURrQjtZQUV6QkksTUFBQUEsRUFBUXRDLE9BQUFBLENBQVFzQyxNQUZTO1lBR3pCcEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFBQUE7U0FIYixDQUFkLENBQUE7SUFLRCxDQUFBO0NBekJvRztBQUF2Ryw4REFBdUc7QUFnQ3ZHLE1BQWE0Qix5QkFBTixTQUFvRGhDLGdCQUFwRDtJQUlMLFlBQW1CZCxPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKWCxXQUFBQSxFQUFhVyxPQUFBQSxDQUFRWCxXQURqQjtZQUVKWSxJQUFBQSxFQUFNRCxPQUFBQSxDQUFRQyxJQUZWO1lBR0pjLFlBQUFBLEVBQWNmLE9BQUFBLENBQVFlLFlBSGxCO1lBSUpiLGVBQUFBLEVBQWlCRixPQUFBQSxDQUFRRSxlQUpyQjtZQUtKQyxrQkFBQUEsRUFBb0JILE9BQUFBLENBQVFHLGtCQUx4QjtZQU1KQyxLQUFBQSxFQUFPSixPQUFBQSxDQUFRSSxLQUFBQTtTQU5qQixDQUFBLENBQUE7UUFTQSxJQUFBLENBQUt1QyxHQUFMLEdBQVdWLFNBQUFBLENBQVU7WUFDbkJDLEtBQUFBLEVBQU8sSUFEWTtZQUVuQmhCLGVBQUFBLEVBQWlCbEIsT0FBQUEsQ0FBUWtCLGVBRk47WUFHbkJILFlBQUFBLEVBQWNmLE9BQUFBLENBQVFlLFlBQUFBO1NBSGIsQ0FBWCxDQUFBO1FBTUEsSUFBQSxDQUFLNkIsTUFBTCxHQUFjSCxZQUFBQSxDQUFhO1lBQUVQLEtBQUFBLEVBQU8sSUFBQTtTQUF0QixDQUFkLENBQUE7SUFDRCxDQUFBO0NBckI0RjtBQUEvRiw4REFBK0Y7QUE0Qi9GLE1BQWFhLG1CQUFOLFNBQThDakMsZ0JBQTlDO0lBR0wsWUFBbUJkLE9BQW5CO1FBQ0UsS0FBQSxDQUFNO1lBQ0pYLFdBQUFBLEVBQWFXLE9BQUFBLENBQVFYLFdBRGpCO1lBRUpZLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFIbEI7WUFJSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSnJCO1lBS0pDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBTHhCO1lBTUpDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBQUFBO1NBTmpCLENBQUEsQ0FBQTtRQVNBLElBQUEsQ0FBS3VDLEdBQUwsR0FBV1YsU0FBQUEsQ0FBVTtZQUNuQkMsS0FBQUEsRUFBTyxJQURZO1lBRW5CaEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFGTjtZQUduQkgsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFBQUE7U0FIYixDQUFYLENBQUE7SUFLRCxDQUFBO0NBbEJzRjtBQUF6RixrREFBeUY7QUEwQnpGLE1BQWFpQywrQkFBTixTQUFzRW5CLHNCQUF0RTtJQVFMLFlBQW1CN0IsT0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSjhCLGlCQUFBQSxFQUFtQjlCLE9BQUFBLENBQVE4QixpQkFEdkI7WUFFSjdCLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFIbEI7WUFJSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSnJCO1lBS0pDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBTHhCO1lBTUpDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBTlg7WUFPSmMsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFQckI7WUFRSmEsaUJBQUFBLEVBQW1CL0IsT0FBQUEsQ0FBUStCLGlCQUFBQTtTQVI3QixDQUFBLENBQUE7UUFXQSxJQUFBLENBQUtZLEdBQUwsR0FBV1YsU0FBQUEsQ0FBVTtZQUNuQkMsS0FBQUEsRUFBTyxJQURZO1lBRW5CaEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFGTjtZQUduQkgsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFBQUE7U0FIYixDQUFYLENBQUE7UUFNQSxJQUFBLENBQUs2QixNQUFMLEdBQWNILFlBQUFBLENBQWE7WUFBRVAsS0FBQUEsRUFBTyxJQUFBO1NBQXRCLENBQWQsQ0FBQTtJQUNELENBQUE7Q0F2QkQ7QUFKRiwwRUFJRTtBQWdDRixNQUFhZSxxQ0FBTixTQUFvRnBCLHNCQUFwRjtJQVNMLFlBQW1CN0IsT0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSjhCLGlCQUFBQSxFQUFtQjlCLE9BQUFBLENBQVE4QixpQkFEdkI7WUFFSjdCLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFIbEI7WUFJSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSnJCO1lBS0pDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBTHhCO1lBTUpDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBTlg7WUFPSmMsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFQckI7WUFRSmEsaUJBQUFBLEVBQW1CL0IsT0FBQUEsQ0FBUStCLGlCQUFBQTtTQVI3QixDQUFBLENBQUE7UUFXQSxJQUFBLENBQUtZLEdBQUwsR0FBV1YsU0FBQUEsQ0FBVTtZQUNuQkMsS0FBQUEsRUFBTyxJQURZO1lBRW5CaEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFGTjtZQUduQkgsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFBQUE7U0FIYixDQUFYLENBQUE7UUFNQSxJQUFBLENBQUt1QixNQUFMLEdBQWNELFlBQUFBLENBQWE7WUFDekJILEtBQUFBLEVBQU8sSUFEa0I7WUFFekJJLE1BQUFBLEVBQVF0QyxPQUFBQSxDQUFRc0MsTUFGUztZQUd6QnBCLGVBQUFBLEVBQWlCbEIsT0FBQUEsQ0FBUWtCLGVBQUFBO1NBSGIsQ0FBZCxDQUFBO1FBTUEsSUFBQSxDQUFLMEIsTUFBTCxHQUFjSCxZQUFBQSxDQUFhO1lBQUVQLEtBQUFBLEVBQU8sSUFBQTtTQUF0QixDQUFkLENBQUE7SUFDRCxDQUFBO0NBOUJEO0FBSkYsc0ZBSUU7QUFzQ0YsTUFBYWdCLHlCQUFOLFNBQWdFckIsc0JBQWhFO0lBR0wsWUFBbUI3QixPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKOEIsaUJBQUFBLEVBQW1COUIsT0FBQUEsQ0FBUThCLGlCQUR2QjtZQUVKN0IsSUFBQUEsRUFBTUQsT0FBQUEsQ0FBUUMsSUFGVjtZQUdKYyxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUhsQjtZQUlKYixlQUFBQSxFQUFpQkYsT0FBQUEsQ0FBUUUsZUFKckI7WUFLSkMsa0JBQUFBLEVBQW9CSCxPQUFBQSxDQUFRRyxrQkFMeEI7WUFNSkMsS0FBQUEsRUFBT0osT0FBQUEsQ0FBUUksS0FOWDtZQU9KYyxlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQVByQjtZQVFKYSxpQkFBQUEsRUFBbUIvQixPQUFBQSxDQUFRK0IsaUJBQUFBO1NBUjdCLENBQUEsQ0FBQTtRQVdBLElBQUEsQ0FBS1ksR0FBTCxHQUFXVixTQUFBQSxDQUFVO1lBQ25CQyxLQUFBQSxFQUFPLElBRFk7WUFFbkJoQixlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQUZOO1lBR25CSCxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUFBQTtTQUhiLENBQVgsQ0FBQTtJQUtELENBQUE7Q0FwQm1IO0FBQXRILDhEQUFzSDtBQTRCdEgsTUFBYW9DLGtDQUFOLFNBQXFFbkMsbUJBQXJFO0lBS0wsWUFBbUJoQixPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKaUIsY0FBQUEsRUFBZ0JqQixPQUFBQSxDQUFRaUIsY0FEcEI7WUFFSmhCLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFIbEI7WUFJSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSnJCO1lBS0pDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBTHhCO1lBTUpDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBTlg7WUFPSmMsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFBQUE7U0FQM0IsQ0FBQSxDQUFBO1FBVUEsSUFBQSxDQUFLeUIsR0FBTCxHQUFXVixTQUFBQSxDQUFVO1lBQ25CQyxLQUFBQSxFQUFPLElBRFk7WUFFbkJoQixlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQUZOO1lBR25CSCxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUFBQTtTQUhiLENBQVgsQ0FBQTtRQU1BLElBQUEsQ0FBS3VCLE1BQUwsR0FBY0QsWUFBQUEsQ0FBYTtZQUN6QkgsS0FBQUEsRUFBTyxJQURrQjtZQUV6QkksTUFBQUEsRUFBUXRDLE9BQUFBLENBQVFzQyxNQUZTO1lBR3pCcEIsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFBQUE7U0FIYixDQUFkLENBQUE7UUFNQSxJQUFBLENBQUswQixNQUFMLEdBQWNILFlBQUFBLENBQWE7WUFBRVAsS0FBQUEsRUFBTyxJQUFBO1NBQXRCLENBQWQsQ0FBQTtJQUNELENBQUE7Q0E3QnlHO0FBQTVHLGdGQUE0RztBQW9DNUcsTUFBYWtCLHNCQUFOLFNBQWlEcEMsbUJBQWpEO0lBR0wsWUFBbUJoQixPQUFuQjtRQUNFLEtBQUEsQ0FBTTtZQUNKaUIsY0FBQUEsRUFBZ0JqQixPQUFBQSxDQUFRaUIsY0FEcEI7WUFFSmhCLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSmMsWUFBQUEsRUFBY2YsT0FBQUEsQ0FBUWUsWUFIbEI7WUFJSmIsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSnJCO1lBS0pDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBTHhCO1lBTUpDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBTlg7WUFPSmMsZUFBQUEsRUFBaUJsQixPQUFBQSxDQUFRa0IsZUFBQUE7U0FQM0IsQ0FBQSxDQUFBO1FBVUEsSUFBQSxDQUFLeUIsR0FBTCxHQUFXVixTQUFBQSxDQUFVO1lBQ25CQyxLQUFBQSxFQUFPLElBRFk7WUFFbkJoQixlQUFBQSxFQUFpQmxCLE9BQUFBLENBQVFrQixlQUZOO1lBR25CSCxZQUFBQSxFQUFjZixPQUFBQSxDQUFRZSxZQUFBQTtTQUhiLENBQVgsQ0FBQTtJQUtELENBQUE7Q0FuQnFGO0FBQXhGLHdEQUF3RjtBQWtDeEYsTUFBYXNDLHFCQUFOLFNBQTZEdEQsb0JBQTdEO0lBSUwsWUFBbUJDLE9BQW5CO1FBQ0UsS0FBQSxDQUFNO1lBQ0pYLFdBQUFBLEVBQWFXLE9BQUFBLENBQVFYLFdBRGpCO1lBRUpZLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSkMsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBQUFBO1NBSDNCLENBQUEsQ0FBQTtRQU1BLElBQUEsQ0FBS29ELGtCQUFMLEdBQTBCLEVBQTFCLENBQUE7SUFDRCxDQUFBO0lBRUQsS0FBQSxDQUFhWCxHQUFiLENBQWlCaEQsS0FBakIsRUFBK0J3QyxLQUEvQjtRQUNFLElBQUksQ0FBQ0EsS0FBTCxFQUFZO1lBQ1YsTUFBTUMsWUFBQUEsR0FBZSxNQUFNLElBQUEsQ0FBS3RDLE1BQUwsQ0FBWTtnQkFBRXlELFdBQUFBLEVBQWE1RCxLQUFBQSxDQUFNNkQsS0FBQUE7YUFBakMsQ0FBM0IsQ0FBQTtZQUNBLElBQUlwQixZQUFBQSxLQUFpQjVDLFNBQXJCLEVBQWdDO2dCQUM5QixNQUFNLElBQUlFLEtBQUosQ0FBVSw4Q0FBVixDQUFOLENBQUE7YUFDRDtTQUNGO1FBRUQsTUFBTWtCLFFBQVEsR0FBOEM7WUFBRW5CLElBQUFBLEVBQU0sS0FBUjtZQUFlbUIsUUFBQUEsRUFBVWpCLEtBQXpCO1lBQWdDQSxLQUFBQTtTQUE1RixDQUFBO1FBQ0EsSUFBQSxDQUFLVSxhQUFMLENBQW1Cb0Qsb0JBQUFBLENBQU9DLGVBQVAsQ0FBdUIvRCxLQUFBQSxDQUFNZ0UsSUFBN0IsQ0FBbkIsQ0FBQSxHQUF5RC9DLFFBQXpELENBQUE7UUFDQSxJQUFBLENBQUswQyxrQkFBTCxDQUF5QixHQUFFM0QsS0FBQUEsQ0FBTTZELEtBQU0sRUFBdkMsQ0FBQSxHQUE0QzVDLFFBQTVDLENBQUE7SUFDRCxDQUFBO0lBRVN4QixhQUFWLENBQXdCRSxHQUF4QjtRQUNFLElBQUksT0FBT0EsR0FBQUEsQ0FBSWlFLFdBQVgsS0FBMkIsUUFBL0IsRUFBeUM7WUFDdkMsT0FBTyxJQUFBLENBQUtsRCxhQUFMLENBQW1Cb0Qsb0JBQUFBLENBQU9DLGVBQVAsQ0FBdUJwRSxHQUFBQSxDQUFJaUUsV0FBM0IsQ0FBbkIsQ0FBUCxDQUFBO1NBQ0Q7UUFFRCxPQUFPLElBQUEsQ0FBS0Qsa0JBQUwsQ0FBeUIsR0FBRWhFLEdBQUFBLENBQUlpRSxXQUFZLEVBQTNDLENBQVAsQ0FBQTtJQUNELENBQUE7Q0FqQ2tIO0FBQXJILHNEQUFxSDtBQTBDckgsTUFBTUssdUJBQUFBLEdBQTBCLENBQUN0RSxHQUFELEVBQUEsRUFBQSxDQUE2QixHQUFFbUUsb0JBQUFBLENBQU9JLFlBQVAsQ0FBb0J2RSxHQUFBQSxDQUFJcUUsSUFBeEIsQ0FBOEIsSUFBR3JFLEdBQUFBLENBQUlrRSxLQUFNLEVBQTFHLENBQUE7QUFFQSxNQUFhTSxrQkFBTixTQUFpQ2hELGdCQUFqQztJQUdMLFlBQW1CekIsV0FBbkI7UUFDRSxLQUFBLENBQU07WUFDSkEsV0FESTtZQUVKWSxJQUFBQSxFQUFNLFFBRkY7WUFHSmMsWUFBQUEsRUFBYzZDLHVCQUhWO1lBSUoxRCxlQUFBQSxFQUFpQixDQUFDUCxLQUFELEVBQUEsRUFBQSxDQUFBLENBQXlCO2dCQUFFRixJQUFBQSxFQUFNLFFBQVI7Z0JBQWtCRSxLQUFBQTthQUEzQyxDQUFBO1NBSm5CLENBQUEsQ0FBQTtRQU9BLElBQUEsQ0FBS2dELEdBQUwsR0FBVyxLQUFBLEVBQU9oRCxLQUFQLEVBQTJCd0MsS0FBM0IsRUFBQSxFQUFBO1lBQ1QsTUFBTTdDLEdBQUFBLEdBQU07Z0JBQUVxRSxJQUFBQSxFQUFNaEUsS0FBQUEsQ0FBTWdFLElBQWQ7Z0JBQW9CSCxLQUFBQSxFQUFPN0QsS0FBQUEsQ0FBTTZELEtBQUFBO2FBQTdDLENBQUE7WUFFQSxJQUFJLENBQUNyQixLQUFMLEVBQVk7Z0JBQ1YsTUFBTUMsWUFBQUEsR0FBZSxNQUFNLElBQUEsQ0FBS3RDLE1BQUwsQ0FBWVIsR0FBWixDQUEzQixDQUFBO2dCQUNBLElBQUk4QyxZQUFBQSxLQUFpQjVDLFNBQXJCLEVBQWdDO29CQUM5QixNQUFNLElBQUlFLEtBQUosQ0FDSCxzREFBRCxHQUEwRCxHQUFFLElBQUEsQ0FBS08sSUFBSyxJQUFHLElBQUEsQ0FBS2MsWUFBTCxDQUFrQnpCLEdBQWxCLENBQXVCLEdBRDVGLENBQU4sQ0FBQTtpQkFHRDthQUNGO1lBRUQsSUFBQSxDQUFLZSxhQUFMLENBQW1CLElBQUEsQ0FBS1UsWUFBTCxDQUFrQnpCLEdBQWxCLENBQW5CLENBQUEsR0FBNkM7Z0JBQzNDRyxJQUFBQSxFQUFNLEtBRHFDO2dCQUUzQ21CLFFBQUFBLEVBQVVqQixLQUZpQztnQkFHM0NBLEtBQUFBLEVBQU9BLEtBQUFBLENBQU1vRSxNQUFBQTthQUhmLENBQUE7UUFLRCxDQWpCRCxDQUFBO0lBa0JELENBQUE7Q0E3QnNGO0FBQXpGLGdEQUF5RjtBQXFDekYsU0FBU0MsaUJBQWlCLENBQWEsRUFDckM1RSxhQURxQyxFQUVyQ0MsV0FBQUEsRUFGRjtJQVFFLE9BQU8sS0FBQSxJQUFBLEVBQUE7UUFDTCxNQUFNRSxhQUFBQSxHQUFnQkgsYUFBQUEsRUFBdEIsQ0FBQTtRQUNBLElBQUlHLGFBQUFBLEtBQWtCQyxTQUF0QixFQUFpQztZQUMvQixJQUFJRCxhQUFBQSxDQUFjRSxJQUFkLEtBQXVCLFFBQTNCLEVBQXFDO2dCQUNuQyxNQUFNLElBQUlDLEtBQUosQ0FBVSxXQUFWLENBQU4sQ0FBQTthQUNEO1lBRUQsT0FBT0gsYUFBQUEsQ0FBY0ksS0FBckIsQ0FBQTtTQUNEO1FBRUQsT0FBT04sV0FBQUEsRUFBQUEsQ0FBY08sR0FBZCxFQUFQLENBQUE7SUFDRCxDQVhELENBQUE7QUFZRCxDQUFBO0FBRUQsU0FBU3FFLG9CQUFvQixDQUFRLEVBQ25DN0UsYUFEbUMsRUFFbkNDLFdBQUFBLEVBRkY7SUFRRSxPQUFPLEtBQUEsSUFBQSxFQUFBO1FBQ0wsTUFBTUUsYUFBQUEsR0FBZ0JILGFBQUFBLEVBQXRCLENBQUE7UUFDQSxJQUFJRyxhQUFBQSxLQUFrQkMsU0FBdEIsRUFBaUM7WUFDL0IsSUFBSUQsYUFBQUEsQ0FBY0UsSUFBZCxLQUF1QixRQUEzQixFQUFxQztnQkFDbkMsT0FBT0QsU0FBUCxDQUFBO2FBQ0Q7WUFFRCxPQUFPRCxhQUFBQSxDQUFjSSxLQUFyQixDQUFBO1NBQ0Q7UUFFRCxPQUFPTixXQUFBQSxFQUFBQSxDQUFjUyxNQUFkLEVBQVAsQ0FBQTtJQUNELENBWEQsQ0FBQTtBQVlELENBQUE7QUFVRCxNQUFhb0UsNEJBQTRCO0lBVXZDLFlBQW1CbEUsT0FBbkI7UUFDRSxJQUFBLENBQUtYLFdBQUwsR0FBbUJXLE9BQUFBLENBQVFYLFdBQTNCLENBQUE7UUFDQSxJQUFBLENBQUtZLElBQUwsR0FBWUQsT0FBQUEsQ0FBUUMsSUFBcEIsQ0FBQTtRQUNBLElBQUEsQ0FBS0MsZUFBTCxHQUF1QkYsT0FBQUEsQ0FBUUUsZUFBL0IsQ0FBQTtRQUNBLElBQUEsQ0FBS0Msa0JBQUwsR0FBMEJILE9BQUFBLENBQVFHLGtCQUFsQyxDQUFBO1FBQ0EsSUFBQSxDQUFLQyxLQUFMLEdBQWFKLE9BQUFBLENBQVFJLEtBQXJCLENBQUE7UUFFQSxJQUFBLENBQUtSLEdBQUwsR0FBV29FLGlCQUFBQSxDQUFrQjtZQUMzQjNFLFdBQUFBLEVBQWEsSUFBQSxDQUFLQSxXQURTO1lBRTNCRCxhQUFBQSxFQUFlLElBQUEsQ0FBS0EsYUFBTCxDQUFtQmtCLElBQW5CLENBQXdCLElBQXhCLENBQUE7U0FGTixDQUFYLENBQUE7UUFLQSxJQUFBLENBQUtSLE1BQUwsR0FBY21FLG9CQUFBQSxDQUFxQjtZQUNqQzVFLFdBQUFBLEVBQWEsSUFBQSxDQUFLQSxXQURlO1lBRWpDRCxhQUFBQSxFQUFlLElBQUEsQ0FBS0EsYUFBTCxDQUFtQmtCLElBQW5CLENBQXdCLElBQXhCLENBQUE7U0FGSCxDQUFkLENBQUE7SUFJRCxDQUFBO0lBRU1DLFlBQVA7UUFDRSxNQUFNSixrQkFBQUEsR0FBcUIsSUFBQSxDQUFLQSxrQkFBaEMsQ0FBQTtRQUNBLE1BQU1SLEtBQUFBLEdBQVEsSUFBQSxDQUFLd0UsWUFBbkIsQ0FBQTtRQUNBLElBQUl4RSxLQUFBQSxLQUFVSCxTQUFkLEVBQXlCO1lBQ3ZCLE9BQU8sRUFBUCxDQUFBO1NBQ0Q7UUFFRCxJQUFJRyxLQUFBQSxDQUFNRixJQUFOLEtBQWUsUUFBbkIsRUFBNkI7WUFDM0IsSUFBSVUsa0JBQUFBLEtBQXVCWCxTQUEzQixFQUFzQztnQkFDcEMsTUFBTSxJQUFJRSxLQUFKLENBQVUsZ0JBQVYsQ0FBTixDQUFBO2FBQ0Q7WUFFRCxPQUFPLENBQUM7b0JBQUVELElBQUFBLEVBQU0sUUFBUjtvQkFBa0JrQixNQUFBQSxFQUFRUixrQkFBQUEsRUFBQUE7aUJBQTNCLENBQVAsQ0FBQTtTQUNEO1FBRUQsT0FBTyxDQUFDO2dCQUFFVixJQUFBQSxFQUFNLEtBQVI7Z0JBQWVrQixNQUFBQSxFQUFRLElBQUEsQ0FBS1QsZUFBTCxDQUFxQlAsS0FBQUEsQ0FBTWlCLFFBQTNCLENBQUE7YUFBeEIsQ0FBUCxDQUFBO0lBQ0QsQ0FBQTtJQUVTeEIsYUFBVjtRQUNFLE9BQU8sSUFBQSxDQUFLK0UsWUFBWixDQUFBO0lBQ0QsQ0FBQTtDQWhEd0Q7QUFBM0Qsb0VBQTJEO0FBbUQzRCxNQUFNQyx3QkFBTixTQUF3REYsNEJBQXhEO0NBQXNHO0FBRXRHLFNBQVNHLGlCQUFpQixDQUFRLEVBQ2hDbkMsS0FBQUEsRUFERjtJQUtFLE9BQU8sS0FBQSxFQUFPdkMsS0FBUCxFQUFBLEVBQUE7UUFDTCxJQUFJdUMsS0FBQUEsQ0FBTTlCLEtBQU4sS0FBZ0JaLFNBQXBCLEVBQStCO1lBQzdCLE1BQU0wQyxLQUFBQSxDQUFNOUIsS0FBTixDQUFZVCxLQUFaLENBQU4sQ0FBQTtTQUYwQyxDQUs1Qyw4Q0FBQTtRQUNBdUMsS0FBQUEsQ0FBTWlDLFlBQU4sR0FBcUI7WUFDbkIxRSxJQUFBQSxFQUFNLEtBRGE7WUFFbkJtQixRQUFBQSxFQUFVakIsS0FGUztZQUduQkEsS0FBQUE7U0FIRixDQUFBO0lBS0QsQ0FYRCxDQUFBO0FBWUQsQ0FBQTtBQUVELFNBQVMyRSxvQkFBb0IsQ0FBZ0IsRUFDM0NwQyxLQUQyQyxFQUUzQ0ksTUFBQUEsRUFBUUMsVUFBQUEsRUFGVjtJQU9FLE9BQU8sS0FBQSxFQUFPNUMsS0FBUCxFQUFxQjJDLE1BQXJCLEVBQUEsRUFBQTtRQUNMLE1BQU1FLFlBQUFBLEdBQWVELFVBQUFBLENBQVc1QyxLQUFYLEVBQWtCMkMsTUFBbEIsQ0FBckIsQ0FENkQsQ0FFN0QsOENBQUE7UUFDQUosS0FBQUEsQ0FBTWlDLFlBQU4sR0FBcUI7WUFDbkIxRSxJQUFBQSxFQUFNLEtBRGE7WUFFbkJtQixRQUFBQSxFQUFVNEIsWUFGUztZQUduQjdDLEtBQUFBLEVBQU82QyxZQUFBQTtTQUhULENBQUE7UUFNQSxPQUFPQSxZQUFQLENBQUE7SUFDRCxDQVZELENBQUE7QUFXRCxDQUFBO0FBT0QsTUFBYStCLGlDQUFOLFNBQStESCx3QkFBL0Q7SUFJTCxZQUFtQnBFLE9BQW5CO1FBQ0UsS0FBQSxDQUFNO1lBQ0pYLFdBQUFBLEVBQWFXLE9BQUFBLENBQVFYLFdBRGpCO1lBRUpZLElBQUFBLEVBQU1ELE9BQUFBLENBQVFDLElBRlY7WUFHSkMsZUFBQUEsRUFBaUJGLE9BQUFBLENBQVFFLGVBSHJCO1lBSUpDLGtCQUFBQSxFQUFvQkgsT0FBQUEsQ0FBUUcsa0JBSnhCO1lBS0pDLEtBQUFBLEVBQU9KLE9BQUFBLENBQVFJLEtBQUFBO1NBTGpCLENBQUEsQ0FBQTtRQVFBLElBQUEsQ0FBS3VDLEdBQUwsR0FBVzBCLGlCQUFBQSxDQUFrQjtZQUMzQm5DLEtBQUFBLEVBQU8sSUFBQTtTQURFLENBQVgsQ0FBQTtRQUlBLElBQUEsQ0FBS0ksTUFBTCxHQUFjZ0Msb0JBQUFBLENBQXFCO1lBQ2pDcEMsS0FBQUEsRUFBTyxJQUQwQjtZQUVqQ0ksTUFBQUEsRUFBUXRDLE9BQUFBLENBQVFzQyxNQUFBQTtTQUZKLENBQWQsQ0FBQTtJQUlELENBQUE7Q0FyQjBHO0FBQTdHLDhFQUE2RyIsImZpbGUiOiJuZW8tb25lLW5vZGUtYmxvY2tjaGFpbi9zcmMvU3RvcmFnZUNhY2hlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmxvY2ssIGNvbW1vbiwgT3V0cHV0LCBPdXRwdXRLZXksIFVJbnQyNTYgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29yZSc7XG5pbXBvcnQge1xuICBBZGRDaGFuZ2UsXG4gIENoYW5nZSxcbiAgQ2hhbmdlU2V0LFxuICBEZWxldGVDaGFuZ2UsXG4gIFJlYWRBbGxTdG9yYWdlLFxuICBSZWFkR2V0QWxsU3RvcmFnZSxcbiAgUmVhZE1ldGFkYXRhU3RvcmFnZSxcbiAgUmVhZFN0b3JhZ2UsXG59IGZyb20gJ0BuZW8tb25lL25vZGUtY29yZSc7XG5pbXBvcnQgeyB1dGlscyBhcyBjb21tb25VdGlscyB9IGZyb20gJ0BuZW8tb25lL3V0aWxzJztcbmltcG9ydCB7IGNvbmNhdCwgZGVmZXIsIEVNUFRZLCBPYnNlcnZhYmxlLCBvZiBhcyBfb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNvbmNhdE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbnR5cGUgVHJhY2tlZENoYW5nZTxLZXksIEFkZFZhbHVlLCBWYWx1ZT4gPVxuICB8IHsgcmVhZG9ubHkgdHlwZTogJ2FkZCc7IHJlYWRvbmx5IGFkZFZhbHVlOiBBZGRWYWx1ZTsgcmVhZG9ubHkgdmFsdWU6IFZhbHVlIH1cbiAgfCB7IHJlYWRvbmx5IHR5cGU6ICdkZWxldGUnOyByZWFkb25seSBrZXk6IEtleSB9O1xudHlwZSBHZXRGdW5jPEtleSwgVmFsdWU+ID0gKChrZXk6IEtleSkgPT4gUHJvbWlzZTxWYWx1ZT4pO1xudHlwZSBUcnlHZXRGdW5jPEtleSwgVmFsdWU+ID0gKChrZXk6IEtleSkgPT4gUHJvbWlzZTxWYWx1ZSB8IHVuZGVmaW5lZD4pO1xuXG5mdW5jdGlvbiBjcmVhdGVHZXQ8S2V5LCBWYWx1ZT4oe1xuICB0cnlHZXRUcmFja2VkLFxuICByZWFkU3RvcmFnZSxcbn06IHtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICByZWFkb25seSB0cnlHZXRUcmFja2VkOiAoKGtleTogS2V5KSA9PiBUcmFja2VkQ2hhbmdlPEtleSwgYW55LCBWYWx1ZT4gfCB1bmRlZmluZWQpO1xuICByZWFkb25seSByZWFkU3RvcmFnZTogKCkgPT4gUmVhZFN0b3JhZ2U8S2V5LCBWYWx1ZT47XG59KTogR2V0RnVuYzxLZXksIFZhbHVlPiB7XG4gIHJldHVybiBhc3luYyAoa2V5OiBLZXkpOiBQcm9taXNlPFZhbHVlPiA9PiB7XG4gICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IHRyeUdldFRyYWNrZWQoa2V5KTtcbiAgICBpZiAodHJhY2tlZENoYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHJhY2tlZENoYW5nZS50eXBlID09PSAnZGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBmb3VuZCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJhY2tlZENoYW5nZS52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVhZFN0b3JhZ2UoKS5nZXQoa2V5KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHJ5R2V0PEtleSwgVmFsdWU+KHtcbiAgdHJ5R2V0VHJhY2tlZCxcbiAgcmVhZFN0b3JhZ2UsXG59OiB7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbiAgcmVhZG9ubHkgdHJ5R2V0VHJhY2tlZDogKChrZXk6IEtleSkgPT4gVHJhY2tlZENoYW5nZTxLZXksIGFueSwgVmFsdWU+IHwgdW5kZWZpbmVkKTtcbiAgcmVhZG9ubHkgcmVhZFN0b3JhZ2U6ICgpID0+IFJlYWRTdG9yYWdlPEtleSwgVmFsdWU+O1xufSk6IFRyeUdldEZ1bmM8S2V5LCBWYWx1ZT4ge1xuICByZXR1cm4gYXN5bmMgKGtleTogS2V5KTogUHJvbWlzZTxWYWx1ZSB8IHVuZGVmaW5lZD4gPT4ge1xuICAgIGNvbnN0IHRyYWNrZWRDaGFuZ2UgPSB0cnlHZXRUcmFja2VkKGtleSk7XG4gICAgaWYgKHRyYWNrZWRDaGFuZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHRyYWNrZWRDaGFuZ2UudHlwZSA9PT0gJ2RlbGV0ZScpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRyYWNrZWRDaGFuZ2UudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlYWRTdG9yYWdlKCkudHJ5R2V0KGtleSk7XG4gIH07XG59XG5cbmludGVyZmFjZSBCYXNlUmVhZFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgcmVhZG9ubHkgcmVhZFN0b3JhZ2U6ICgpID0+IFJlYWRTdG9yYWdlPEtleSwgVmFsdWU+O1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNyZWF0ZUFkZENoYW5nZTogKCh2YWx1ZTogQWRkVmFsdWUpID0+IEFkZENoYW5nZSk7XG4gIHJlYWRvbmx5IGNyZWF0ZURlbGV0ZUNoYW5nZT86ICgoa2V5OiBLZXkpID0+IERlbGV0ZUNoYW5nZSk7XG4gIHJlYWRvbmx5IG9uQWRkPzogKCh2YWx1ZTogQWRkVmFsdWUpID0+IFByb21pc2U8dm9pZD4pO1xufVxuXG5leHBvcnQgY2xhc3MgQmFzZVJlYWRTdG9yYWdlQ2FjaGU8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IHtcbiAgcHVibGljIHJlYWRvbmx5IGdldDogR2V0RnVuYzxLZXksIFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IHRyeUdldDogVHJ5R2V0RnVuYzxLZXksIFZhbHVlPjtcbiAgcHVibGljIHJlYWRvbmx5IG9uQWRkOiAoKHZhbHVlOiBBZGRWYWx1ZSkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSByZWFkb25seS1rZXl3b3JkXG4gIHB1YmxpYyByZWFkb25seSBtdXRhYmxlVmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IFRyYWNrZWRDaGFuZ2U8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+IH07XG4gIHByb3RlY3RlZCByZWFkb25seSByZWFkU3RvcmFnZTogKCkgPT4gUmVhZFN0b3JhZ2U8S2V5LCBWYWx1ZT47XG4gIHByb3RlY3RlZCByZWFkb25seSBjcmVhdGVBZGRDaGFuZ2U6ICgodmFsdWU6IEFkZFZhbHVlKSA9PiBBZGRDaGFuZ2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY3JlYXRlRGVsZXRlQ2hhbmdlOiAoKGtleTogS2V5KSA9PiBEZWxldGVDaGFuZ2UpIHwgdW5kZWZpbmVkO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBCYXNlUmVhZFN0b3JhZ2VDYWNoZU9wdGlvbnM8S2V5LCBBZGRWYWx1ZSwgVmFsdWU+KSB7XG4gICAgdGhpcy5yZWFkU3RvcmFnZSA9IG9wdGlvbnMucmVhZFN0b3JhZ2U7XG4gICAgdGhpcy5uYW1lID0gb3B0aW9ucy5uYW1lO1xuICAgIHRoaXMuY3JlYXRlQWRkQ2hhbmdlID0gb3B0aW9ucy5jcmVhdGVBZGRDaGFuZ2U7XG4gICAgdGhpcy5jcmVhdGVEZWxldGVDaGFuZ2UgPSBvcHRpb25zLmNyZWF0ZURlbGV0ZUNoYW5nZTtcbiAgICB0aGlzLm9uQWRkID0gb3B0aW9ucy5vbkFkZDtcbiAgICB0aGlzLm11dGFibGVWYWx1ZXMgPSB7fTtcblxuICAgIHRoaXMuZ2V0ID0gY3JlYXRlR2V0KHtcbiAgICAgIHJlYWRTdG9yYWdlOiB0aGlzLnJlYWRTdG9yYWdlLFxuICAgICAgdHJ5R2V0VHJhY2tlZDogdGhpcy50cnlHZXRUcmFja2VkLmJpbmQodGhpcyksXG4gICA