@data-client/normalizr
Version:
Normalizes and denormalizes JSON according to schema for Redux and Flux applications
127 lines (115 loc) • 19.1 kB
JavaScript
import { getCheckLoop } from './getCheckLoop.js';
import { ImmDelegate } from '../delegate/Delegate.imm.js';
import { INVALID } from '../denormalize/symbol.js';
/** ImmutableJS state table that supports setIn with variable path lengths */
/** Full normalize() logic for ImmutableJS state */
export class ImmNormalizeDelegate extends ImmDelegate {
constructor(state, actionMeta) {
super(state);
// Override with mutable table type that supports variable path lengths
this.newEntities = new Map();
this.newIndexes = new Map();
this.entitiesMeta = state.entitiesMeta;
this.meta = actionMeta;
this.checkLoop = getCheckLoop();
}
getNewEntity(key, pk) {
return this.getNewEntities(key).get(pk);
}
getNewEntities(key) {
// first time we come across this type of entity
if (!this.newEntities.has(key)) {
this.newEntities.set(key, new Map());
}
return this.newEntities.get(key);
}
getNewIndexes(key) {
if (!this.newIndexes.has(key)) {
this.newIndexes.set(key, new Map());
}
return this.newIndexes.get(key);
}
/** Updates an entity using merge lifecycles when it has previously been set */
mergeEntity(schema, pk, incomingEntity) {
const key = schema.key;
// default when this is completely new entity
let nextEntity = incomingEntity;
let nextMeta = this.meta;
// if we already processed this entity during this normalization (in another nested place)
let entity = this.getNewEntity(key, pk);
if (entity) {
nextEntity = schema.merge(entity, incomingEntity);
} else {
// if we find it in the store
entity = this.getEntity(key, pk);
if (entity) {
const meta = this.getMeta(key, pk);
nextEntity = schema.mergeWithStore(meta, nextMeta, entity, incomingEntity);
nextMeta = schema.mergeMetaWithStore(meta, nextMeta, entity, incomingEntity);
}
}
// once we have computed the merged values, set them
this.setEntity(schema, pk, nextEntity, nextMeta);
}
/** Sets an entity overwriting any previously set values */
setEntity(schema, pk, entity, meta = this.meta) {
const key = schema.key;
const newEntities = this.getNewEntities(key);
const updateMeta = !newEntities.has(pk);
newEntities.set(pk, entity);
// update index
if (schema.indexes) {
this.handleIndexes(pk, key, schema.indexes, entity);
}
// set this after index updates so we know what indexes to remove from
this._setEntity(key, pk, entity);
if (updateMeta) this._setMeta(key, pk, meta);
}
/** Invalidates an entity, potentially triggering suspense */
invalidate({
key
}, pk) {
// set directly: any queued updates are meaningless with delete
this.setEntity({
key
}, pk, INVALID);
}
_setEntity(key, pk, entity) {
this.entities = this.entities.setIn([key, pk], entity);
}
_setMeta(key, pk, meta) {
this.entitiesMeta = this.entitiesMeta.setIn([key, pk], meta);
}
getMeta(key, pk) {
return this.entitiesMeta.getIn([key, pk]);
}
handleIndexes(id, entityKey, schemaIndexes, entity) {
const indexes = this.getNewIndexes(entityKey);
const existingEntity = this.getEntity(entityKey, id);
for (const index of schemaIndexes) {
var _entity$index;
if (!indexes.has(index)) {
indexes.set(index, new Map());
}
const indexMap = indexes.get(index);
// If entity already exists, remove old index entry
if (existingEntity) {
var _existingEntity$index;
const oldIndexValue = (_existingEntity$index = existingEntity[index]) != null ? _existingEntity$index : existingEntity.get == null ? void 0 : existingEntity.get(index);
if (oldIndexValue !== undefined) {
indexMap.set(oldIndexValue, INVALID);
// Write invalidation to immutable indexes
this.indexes = this.indexes.setIn([entityKey, index, oldIndexValue], INVALID);
}
}
// Add new index entry
const newIndexValue = (_entity$index = entity[index]) != null ? _entity$index : entity.get == null ? void 0 : entity.get(index);
if (newIndexValue !== undefined) {
indexMap.set(newIndexValue, id);
// Update the immutable indexes
this.indexes = this.indexes.setIn([entityKey, index, newIndexValue], id);
}
}
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRDaGVja0xvb3AiLCJJbW1EZWxlZ2F0ZSIsIklOVkFMSUQiLCJJbW1Ob3JtYWxpemVEZWxlZ2F0ZSIsImNvbnN0cnVjdG9yIiwic3RhdGUiLCJhY3Rpb25NZXRhIiwibmV3RW50aXRpZXMiLCJNYXAiLCJuZXdJbmRleGVzIiwiZW50aXRpZXNNZXRhIiwibWV0YSIsImNoZWNrTG9vcCIsImdldE5ld0VudGl0eSIsImtleSIsInBrIiwiZ2V0TmV3RW50aXRpZXMiLCJnZXQiLCJoYXMiLCJzZXQiLCJnZXROZXdJbmRleGVzIiwibWVyZ2VFbnRpdHkiLCJzY2hlbWEiLCJpbmNvbWluZ0VudGl0eSIsIm5leHRFbnRpdHkiLCJuZXh0TWV0YSIsImVudGl0eSIsIm1lcmdlIiwiZ2V0RW50aXR5IiwiZ2V0TWV0YSIsIm1lcmdlV2l0aFN0b3JlIiwibWVyZ2VNZXRhV2l0aFN0b3JlIiwic2V0RW50aXR5IiwidXBkYXRlTWV0YSIsImluZGV4ZXMiLCJoYW5kbGVJbmRleGVzIiwiX3NldEVudGl0eSIsIl9zZXRNZXRhIiwiaW52YWxpZGF0ZSIsImVudGl0aWVzIiwic2V0SW4iLCJnZXRJbiIsImlkIiwiZW50aXR5S2V5Iiwic2NoZW1hSW5kZXhlcyIsImV4aXN0aW5nRW50aXR5IiwiaW5kZXgiLCJfZW50aXR5JGluZGV4IiwiaW5kZXhNYXAiLCJfZXhpc3RpbmdFbnRpdHkkaW5kZXgiLCJvbGRJbmRleFZhbHVlIiwidW5kZWZpbmVkIiwibmV3SW5kZXhWYWx1ZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ub3JtYWxpemUvTm9ybWFsaXplRGVsZWdhdGUuaW1tLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElOb3JtYWxpemVEZWxlZ2F0ZSwgTWVyZ2VhYmxlIH0gZnJvbSAnLi4vaW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IGdldENoZWNrTG9vcCB9IGZyb20gJy4vZ2V0Q2hlY2tMb29wLmpzJztcbmltcG9ydCB7XG4gIEltbURlbGVnYXRlLFxuICBJbW11dGFibGVKU0VudGl0eVRhYmxlLFxufSBmcm9tICcuLi9kZWxlZ2F0ZS9EZWxlZ2F0ZS5pbW0uanMnO1xuaW1wb3J0IHsgSU5WQUxJRCB9IGZyb20gJy4uL2Rlbm9ybWFsaXplL3N5bWJvbC5qcyc7XG5cbi8qKiBJbW11dGFibGVKUyBzdGF0ZSB0YWJsZSB0aGF0IHN1cHBvcnRzIHNldEluIHdpdGggdmFyaWFibGUgcGF0aCBsZW5ndGhzICovXG5leHBvcnQgaW50ZXJmYWNlIEltbXV0YWJsZUpTTXV0YWJsZVRhYmxlIHtcbiAgZ2V0KGtleTogc3RyaW5nKTogYW55O1xuICBnZXRJbihrOiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdKTogYW55O1xuICBzZXRJbihrOiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdLCB2YWx1ZTogYW55KTogSW1tdXRhYmxlSlNNdXRhYmxlVGFibGU7XG4gIGhhc0luPyhrOiByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdKTogYm9vbGVhbjtcbn1cblxuLyoqIEZ1bGwgbm9ybWFsaXplKCkgbG9naWMgZm9yIEltbXV0YWJsZUpTIHN0YXRlICovXG5leHBvcnQgY2xhc3MgSW1tTm9ybWFsaXplRGVsZWdhdGVcbiAgZXh0ZW5kcyBJbW1EZWxlZ2F0ZVxuICBpbXBsZW1lbnRzIElOb3JtYWxpemVEZWxlZ2F0ZVxue1xuICAvLyBPdmVycmlkZSB3aXRoIG11dGFibGUgdGFibGUgdHlwZSB0aGF0IHN1cHBvcnRzIHZhcmlhYmxlIHBhdGggbGVuZ3Roc1xuICBkZWNsYXJlIGVudGl0aWVzOiBJbW11dGFibGVKU011dGFibGVUYWJsZTtcbiAgZGVjbGFyZSBpbmRleGVzOiBJbW11dGFibGVKU011dGFibGVUYWJsZTtcbiAgZGVjbGFyZSBlbnRpdGllc01ldGE6IEltbXV0YWJsZUpTTXV0YWJsZVRhYmxlO1xuXG4gIGRlY2xhcmUgcmVhZG9ubHkgbWV0YTogeyBmZXRjaGVkQXQ6IG51bWJlcjsgZGF0ZTogbnVtYmVyOyBleHBpcmVzQXQ6IG51bWJlciB9O1xuICBkZWNsYXJlIGNoZWNrTG9vcDogKGVudGl0eUtleTogc3RyaW5nLCBwazogc3RyaW5nLCBpbnB1dDogb2JqZWN0KSA9PiBib29sZWFuO1xuXG4gIHByb3RlY3RlZCBuZXdFbnRpdGllcyA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBhbnk+PigpO1xuICBwcm90ZWN0ZWQgbmV3SW5kZXhlcyA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBhbnk+PigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHN0YXRlOiB7XG4gICAgICBlbnRpdGllczogSW1tdXRhYmxlSlNNdXRhYmxlVGFibGU7XG4gICAgICBpbmRleGVzOiBJbW11dGFibGVKU011dGFibGVUYWJsZTtcbiAgICAgIGVudGl0aWVzTWV0YTogSW1tdXRhYmxlSlNNdXRhYmxlVGFibGU7XG4gICAgfSxcbiAgICBhY3Rpb25NZXRhOiB7IGZldGNoZWRBdDogbnVtYmVyOyBkYXRlOiBudW1iZXI7IGV4cGlyZXNBdDogbnVtYmVyIH0sXG4gICkge1xuICAgIHN1cGVyKFxuICAgICAgc3RhdGUgYXMge1xuICAgICAgICBlbnRpdGllczogSW1tdXRhYmxlSlNFbnRpdHlUYWJsZTtcbiAgICAgICAgaW5kZXhlczogSW1tdXRhYmxlSlNFbnRpdHlUYWJsZTtcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLmVudGl0aWVzTWV0YSA9IHN0YXRlLmVudGl0aWVzTWV0YTtcbiAgICB0aGlzLm1ldGEgPSBhY3Rpb25NZXRhO1xuICAgIHRoaXMuY2hlY2tMb29wID0gZ2V0Q2hlY2tMb29wKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0TmV3RW50aXR5KGtleTogc3RyaW5nLCBwazogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TmV3RW50aXRpZXMoa2V5KS5nZXQocGspO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldE5ld0VudGl0aWVzKGtleTogc3RyaW5nKTogTWFwPHN0cmluZywgYW55PiB7XG4gICAgLy8gZmlyc3QgdGltZSB3ZSBjb21lIGFjcm9zcyB0aGlzIHR5cGUgb2YgZW50aXR5XG4gICAgaWYgKCF0aGlzLm5ld0VudGl0aWVzLmhhcyhrZXkpKSB7XG4gICAgICB0aGlzLm5ld0VudGl0aWVzLnNldChrZXksIG5ldyBNYXAoKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLm5ld0VudGl0aWVzLmdldChrZXkpIGFzIE1hcDxzdHJpbmcsIGFueT47XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0TmV3SW5kZXhlcyhrZXk6IHN0cmluZyk6IE1hcDxzdHJpbmcsIGFueT4ge1xuICAgIGlmICghdGhpcy5uZXdJbmRleGVzLmhhcyhrZXkpKSB7XG4gICAgICB0aGlzLm5ld0luZGV4ZXMuc2V0KGtleSwgbmV3IE1hcCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmV3SW5kZXhlcy5nZXQoa2V5KSBhcyBNYXA8c3RyaW5nLCBhbnk+O1xuICB9XG5cbiAgLyoqIFVwZGF0ZXMgYW4gZW50aXR5IHVzaW5nIG1lcmdlIGxpZmVjeWNsZXMgd2hlbiBpdCBoYXMgcHJldmlvdXNseSBiZWVuIHNldCAqL1xuICBtZXJnZUVudGl0eShcbiAgICBzY2hlbWE6IE1lcmdlYWJsZSAmIHsgaW5kZXhlcz86IGFueSB9LFxuICAgIHBrOiBzdHJpbmcsXG4gICAgaW5jb21pbmdFbnRpdHk6IGFueSxcbiAgKSB7XG4gICAgY29uc3Qga2V5ID0gc2NoZW1hLmtleTtcblxuICAgIC8vIGRlZmF1bHQgd2hlbiB0aGlzIGlzIGNvbXBsZXRlbHkgbmV3IGVudGl0eVxuICAgIGxldCBuZXh0RW50aXR5ID0gaW5jb21pbmdFbnRpdHk7XG4gICAgbGV0IG5leHRNZXRhID0gdGhpcy5tZXRhO1xuXG4gICAgLy8gaWYgd2UgYWxyZWFkeSBwcm9jZXNzZWQgdGhpcyBlbnRpdHkgZHVyaW5nIHRoaXMgbm9ybWFsaXphdGlvbiAoaW4gYW5vdGhlciBuZXN0ZWQgcGxhY2UpXG4gICAgbGV0IGVudGl0eSA9IHRoaXMuZ2V0TmV3RW50aXR5KGtleSwgcGspO1xuICAgIGlmIChlbnRpdHkpIHtcbiAgICAgIG5leHRFbnRpdHkgPSBzY2hlbWEubWVyZ2UoZW50aXR5LCBpbmNvbWluZ0VudGl0eSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIHdlIGZpbmQgaXQgaW4gdGhlIHN0b3JlXG4gICAgICBlbnRpdHkgPSB0aGlzLmdldEVudGl0eShrZXksIHBrKTtcbiAgICAgIGlmIChlbnRpdHkpIHtcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0TWV0YShrZXksIHBrKTtcbiAgICAgICAgbmV4dEVudGl0eSA9IHNjaGVtYS5tZXJnZVdpdGhTdG9yZShcbiAgICAgICAgICBtZXRhLFxuICAgICAgICAgIG5leHRNZXRhLFxuICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICBpbmNvbWluZ0VudGl0eSxcbiAgICAgICAgKTtcbiAgICAgICAgbmV4dE1ldGEgPSBzY2hlbWEubWVyZ2VNZXRhV2l0aFN0b3JlKFxuICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgbmV4dE1ldGEsXG4gICAgICAgICAgZW50aXR5LFxuICAgICAgICAgIGluY29taW5nRW50aXR5LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG9uY2Ugd2UgaGF2ZSBjb21wdXRlZCB0aGUgbWVyZ2VkIHZhbHVlcywgc2V0IHRoZW1cbiAgICB0aGlzLnNldEVudGl0eShzY2hlbWEsIHBrLCBuZXh0RW50aXR5LCBuZXh0TWV0YSk7XG4gIH1cblxuICAvKiogU2V0cyBhbiBlbnRpdHkgb3ZlcndyaXRpbmcgYW55IHByZXZpb3VzbHkgc2V0IHZhbHVlcyAqL1xuICBzZXRFbnRpdHkoXG4gICAgc2NoZW1hOiB7IGtleTogc3RyaW5nOyBpbmRleGVzPzogYW55IH0sXG4gICAgcGs6IHN0cmluZyxcbiAgICBlbnRpdHk6IGFueSxcbiAgICBtZXRhOiB7IGZldGNoZWRBdDogbnVtYmVyOyBkYXRlOiBudW1iZXI7IGV4cGlyZXNBdDogbnVtYmVyIH0gPSB0aGlzLm1ldGEsXG4gICkge1xuICAgIGNvbnN0IGtleSA9IHNjaGVtYS5rZXk7XG4gICAgY29uc3QgbmV3RW50aXRpZXMgPSB0aGlzLmdldE5ld0VudGl0aWVzKGtleSk7XG4gICAgY29uc3QgdXBkYXRlTWV0YSA9ICFuZXdFbnRpdGllcy5oYXMocGspO1xuICAgIG5ld0VudGl0aWVzLnNldChwaywgZW50aXR5KTtcblxuICAgIC8vIHVwZGF0ZSBpbmRleFxuICAgIGlmIChzY2hlbWEuaW5kZXhlcykge1xuICAgICAgdGhpcy5oYW5kbGVJbmRleGVzKHBrLCBrZXksIHNjaGVtYS5pbmRleGVzLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIC8vIHNldCB0aGlzIGFmdGVyIGluZGV4IHVwZGF0ZXMgc28gd2Uga25vdyB3aGF0IGluZGV4ZXMgdG8gcmVtb3ZlIGZyb21cbiAgICB0aGlzLl9zZXRFbnRpdHkoa2V5LCBwaywgZW50aXR5KTtcblxuICAgIGlmICh1cGRhdGVNZXRhKSB0aGlzLl9zZXRNZXRhKGtleSwgcGssIG1ldGEpO1xuICB9XG5cbiAgLyoqIEludmFsaWRhdGVzIGFuIGVudGl0eSwgcG90ZW50aWFsbHkgdHJpZ2dlcmluZyBzdXNwZW5zZSAqL1xuICBpbnZhbGlkYXRlKHsga2V5IH06IHsga2V5OiBzdHJpbmcgfSwgcGs6IHN0cmluZykge1xuICAgIC8vIHNldCBkaXJlY3RseTogYW55IHF1ZXVlZCB1cGRhdGVzIGFyZSBtZWFuaW5nbGVzcyB3aXRoIGRlbGV0ZVxuICAgIHRoaXMuc2V0RW50aXR5KHsga2V5IH0sIHBrLCBJTlZBTElEKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfc2V0RW50aXR5KGtleTogc3RyaW5nLCBwazogc3RyaW5nLCBlbnRpdHk6IGFueSkge1xuICAgIHRoaXMuZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzLnNldEluKFtrZXksIHBrXSwgZW50aXR5KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfc2V0TWV0YShcbiAgICBrZXk6IHN0cmluZyxcbiAgICBwazogc3RyaW5nLFxuICAgIG1ldGE6IHsgZmV0Y2hlZEF0OiBudW1iZXI7IGRhdGU6IG51bWJlcjsgZXhwaXJlc0F0OiBudW1iZXIgfSxcbiAgKSB7XG4gICAgdGhpcy5lbnRpdGllc01ldGEgPSB0aGlzLmVudGl0aWVzTWV0YS5zZXRJbihba2V5LCBwa10sIG1ldGEpO1xuICB9XG5cbiAgZ2V0TWV0YShrZXk6IHN0cmluZywgcGs6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmVudGl0aWVzTWV0YS5nZXRJbihba2V5LCBwa10pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZUluZGV4ZXMoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBlbnRpdHlLZXk6IHN0cmluZyxcbiAgICBzY2hlbWFJbmRleGVzOiBzdHJpbmdbXSxcbiAgICBlbnRpdHk6IGFueSxcbiAgKSB7XG4gICAgY29uc3QgaW5kZXhlcyA9IHRoaXMuZ2V0TmV3SW5kZXhlcyhlbnRpdHlLZXkpO1xuICAgIGNvbnN0IGV4aXN0aW5nRW50aXR5ID0gdGhpcy5nZXRFbnRpdHkoZW50aXR5S2V5LCBpZCk7XG5cbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIHNjaGVtYUluZGV4ZXMpIHtcbiAgICAgIGlmICghaW5kZXhlcy5oYXMoaW5kZXgpKSB7XG4gICAgICAgIGluZGV4ZXMuc2V0KGluZGV4LCBuZXcgTWFwKCkpO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXhNYXAgPSBpbmRleGVzLmdldChpbmRleCk7XG5cbiAgICAgIC8vIElmIGVudGl0eSBhbHJlYWR5IGV4aXN0cywgcmVtb3ZlIG9sZCBpbmRleCBlbnRyeVxuICAgICAgaWYgKGV4aXN0aW5nRW50aXR5KSB7XG4gICAgICAgIGNvbnN0IG9sZEluZGV4VmFsdWUgPVxuICAgICAgICAgIGV4aXN0aW5nRW50aXR5W2luZGV4XSA/PyBleGlzdGluZ0VudGl0eS5nZXQ/LihpbmRleCk7XG4gICAgICAgIGlmIChvbGRJbmRleFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpbmRleE1hcC5zZXQob2xkSW5kZXhWYWx1ZSwgSU5WQUxJRCk7XG4gICAgICAgICAgLy8gV3JpdGUgaW52YWxpZGF0aW9uIHRvIGltbXV0YWJsZSBpbmRleGVzXG4gICAgICAgICAgdGhpcy5pbmRleGVzID0gdGhpcy5pbmRleGVzLnNldEluKFxuICAgICAgICAgICAgW2VudGl0eUtleSwgaW5kZXgsIG9sZEluZGV4VmFsdWVdLFxuICAgICAgICAgICAgSU5WQUxJRCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBuZXcgaW5kZXggZW50cnlcbiAgICAgIGNvbnN0IG5ld0luZGV4VmFsdWUgPSBlbnRpdHlbaW5kZXhdID8/IGVudGl0eS5nZXQ/LihpbmRleCk7XG4gICAgICBpZiAobmV3SW5kZXhWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4TWFwLnNldChuZXdJbmRleFZhbHVlLCBpZCk7XG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgaW1tdXRhYmxlIGluZGV4ZXNcbiAgICAgICAgdGhpcy5pbmRleGVzID0gdGhpcy5pbmRleGVzLnNldEluKFxuICAgICAgICAgIFtlbnRpdHlLZXksIGluZGV4LCBuZXdJbmRleFZhbHVlXSxcbiAgICAgICAgICBpZCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQ0EsU0FBU0EsWUFBWSxRQUFRLG1CQUFtQjtBQUNoRCxTQUNFQyxXQUFXLFFBRU4sNkJBQTZCO0FBQ3BDLFNBQVNDLE9BQU8sUUFBUSwwQkFBMEI7O0FBRWxEOztBQVFBO0FBQ0EsT0FBTyxNQUFNQyxvQkFBb0IsU0FDdkJGLFdBQVcsQ0FFckI7RUFZRUcsV0FBV0EsQ0FDVEMsS0FJQyxFQUNEQyxVQUFrRSxFQUNsRTtJQUNBLEtBQUssQ0FDSEQsS0FJRixDQUFDO0lBeEJIO0lBQUEsS0FRVUUsV0FBVyxHQUFHLElBQUlDLEdBQUcsQ0FBMkIsQ0FBQztJQUFBLEtBQ2pEQyxVQUFVLEdBQUcsSUFBSUQsR0FBRyxDQUEyQixDQUFDO0lBZ0J4RCxJQUFJLENBQUNFLFlB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LENBQUNkLGFBQWEsQ0FBQ3VCLFNBQVMsQ0FBQztJQUM3QyxNQUFNRSxjQUFjLEdBQUcsSUFBSSxDQUFDakIsU0FBUyxDQUFDZSxTQUFTLEVBQUVELEVBQUUsQ0FBQztJQUVwRCxLQUFLLE1BQU1JLEtBQUssSUFBSUYsYUFBYSxFQUFFO01BQUEsSUFBQUcsYUFBQTtNQUNqQyxJQUFJLENBQUNiLE9BQU8sQ0FBQ2hCLEdBQUcsQ0FBQzRCLEtBQUssQ0FBQyxFQUFFO1FBQ3ZCWixPQUFPLENBQUNmLEdBQUcsQ0FBQzJCLEtBQUssRUFBRSxJQUFJdEMsR0FBRyxDQUFDLENBQUMsQ0FBQztNQUMvQjtNQUNBLE1BQU13QyxRQUFRLEdBQUdkLE9BQU8sQ0FBQ2pCLEdBQUcsQ0FBQzZCLEtBQUssQ0FBQzs7TUFFbkM7TUFDQSxJQUFJRCxjQUFjLEVBQUU7UUFBQSxJQUFBSSxxQkFBQTtRQUNsQixNQUFNQyxhQUFhLElBQUFELHFCQUFBLEdBQ2pCSixjQUFjLENBQUNDLEtBQUssQ0FBQyxZQUFBRyxxQkFBQSxHQUFJSixjQUFjLENBQUM1QixHQUFHLG9CQUFsQjRCLGNBQWMsQ0FBQzVCLEdBQUcsQ0FBRzZCLEtBQUssQ0FBQztRQUN0RCxJQUFJSSxhQUFhLEtBQUtDLFNBQVMsRUFBRTtVQUMvQkgsUUFBUSxDQUFDN0IsR0FBRyxDQUFDK0IsYUFBYSxFQUFFaEQsT0FBTyxDQUFDO1VBQ3BDO1VBQ0EsSUFBSSxDQUFDZ0MsT0FBTyxHQUFHLElBQUksQ0FBQ0EsT0FBTyxDQUFDTSxLQUFLLENBQy9CLENBQUNHLFNBQVMsRUFBRUcsS0FBSyxFQUFFSSxhQUFhLENBQUMsRUFDakNoRCxPQUNGLENBQUM7UUFDSDtNQUNGOztNQUVBO01BQ0EsTUFBTWtELGFBQWEsSUFBQUwsYUFBQSxHQUFHckIsTUFBTSxDQUFDb0IsS0FBSyxDQUFDLFlBQUFDLGFBQUEsR0FBSXJCLE1BQU0sQ0FBQ1QsR0FBRyxvQkFBVlMsTUFBTSxDQUFDVCxHQUFHLENBQUc2QixLQUFLLENBQUM7TUFDMUQsSUFBSU0sYUFBYSxLQUFLRCxTQUFTLEVBQUU7UUFDL0JILFFBQVEsQ0FBQzdCLEdBQUcsQ0FBQ2lDLGFBQWEsRUFBRVYsRUFBRSxDQUFDO1FBQy9CO1FBQ0EsSUFBSSxDQUFDUixPQUFPLEdBQUcsSUFBSSxDQUFDQSxPQUFPLENBQUNNLEtBQUssQ0FDL0IsQ0FBQ0csU0FBUyxFQUFFRyxLQUFLLEVBQUVNLGFBQWEsQ0FBQyxFQUNqQ1YsRUFDRixDQUFDO01BQ0g7SUFDRjtFQUNGO0FBQ0YiLCJpZ25vcmVMaXN0IjpbXX0=