@neo-one/node-blockchain-esnext-cjs
Version:
NEO•ONE NEO blockchain implementation.
559 lines (558 loc) • 85 kB
JavaScript
"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