UNPKG

@data-client/normalizr

Version:

Normalizes and denormalizes JSON according to schema for Redux and Flux applications

127 lines (115 loc) 19.1 kB
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=