UNPKG

@angular/core

Version:

Angular - the core framework

1,068 lines 88.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { looseIdentical } from '../../util/comparison'; import { stringify } from '../../util/stringify'; import { isListLikeIterable, iterateListLike } from '../change_detection_util'; export class DefaultIterableDifferFactory { constructor() { } /** * @param {?} obj * @return {?} */ supports(obj) { return isListLikeIterable(obj); } /** * @template V * @param {?=} trackByFn * @return {?} */ create(trackByFn) { return new DefaultIterableDiffer(trackByFn); } } /** @type {?} */ const trackByIdentity = (/** * @param {?} index * @param {?} item * @return {?} */ (index, item) => item); const ɵ0 = trackByIdentity; /** * @deprecated v4.0.0 - Should not be part of public API. * \@publicApi * @template V */ export class DefaultIterableDiffer { /** * @param {?=} trackByFn */ constructor(trackByFn) { this.length = 0; // Keeps track of the used records at any point in time (during & across `_check()` calls) this._linkedRecords = null; // Keeps track of the removed records at any point in time during `_check()` calls. this._unlinkedRecords = null; this._previousItHead = null; this._itHead = null; this._itTail = null; this._additionsHead = null; this._additionsTail = null; this._movesHead = null; this._movesTail = null; this._removalsHead = null; this._removalsTail = null; // Keeps track of records where custom track by is the same, but item identity has changed this._identityChangesHead = null; this._identityChangesTail = null; this._trackByFn = trackByFn || trackByIdentity; } /** * @param {?} fn * @return {?} */ forEachItem(fn) { /** @type {?} */ let record; for (record = this._itHead; record !== null; record = record._next) { fn(record); } } /** * @param {?} fn * @return {?} */ forEachOperation(fn) { /** @type {?} */ let nextIt = this._itHead; /** @type {?} */ let nextRemove = this._removalsHead; /** @type {?} */ let addRemoveOffset = 0; /** @type {?} */ let moveOffsets = null; while (nextIt || nextRemove) { // Figure out which is the next record to process // Order: remove, add, move /** @type {?} */ const record = !nextRemove || nextIt && (/** @type {?} */ (nextIt.currentIndex)) < getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? (/** @type {?} */ (nextIt)) : nextRemove; /** @type {?} */ const adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets); /** @type {?} */ const currentIndex = record.currentIndex; // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary if (record === nextRemove) { addRemoveOffset--; nextRemove = nextRemove._nextRemoved; } else { nextIt = (/** @type {?} */ (nextIt))._next; if (record.previousIndex == null) { addRemoveOffset++; } else { // INVARIANT: currentIndex < previousIndex if (!moveOffsets) moveOffsets = []; /** @type {?} */ const localMovePreviousIndex = adjPreviousIndex - addRemoveOffset; /** @type {?} */ const localCurrentIndex = (/** @type {?} */ (currentIndex)) - addRemoveOffset; if (localMovePreviousIndex != localCurrentIndex) { for (let i = 0; i < localMovePreviousIndex; i++) { /** @type {?} */ const offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0); /** @type {?} */ const index = offset + i; if (localCurrentIndex <= index && index < localMovePreviousIndex) { moveOffsets[i] = offset + 1; } } /** @type {?} */ const previousIndex = record.previousIndex; moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex; } } } if (adjPreviousIndex !== currentIndex) { fn(record, adjPreviousIndex, currentIndex); } } } /** * @param {?} fn * @return {?} */ forEachPreviousItem(fn) { /** @type {?} */ let record; for (record = this._previousItHead; record !== null; record = record._nextPrevious) { fn(record); } } /** * @param {?} fn * @return {?} */ forEachAddedItem(fn) { /** @type {?} */ let record; for (record = this._additionsHead; record !== null; record = record._nextAdded) { fn(record); } } /** * @param {?} fn * @return {?} */ forEachMovedItem(fn) { /** @type {?} */ let record; for (record = this._movesHead; record !== null; record = record._nextMoved) { fn(record); } } /** * @param {?} fn * @return {?} */ forEachRemovedItem(fn) { /** @type {?} */ let record; for (record = this._removalsHead; record !== null; record = record._nextRemoved) { fn(record); } } /** * @param {?} fn * @return {?} */ forEachIdentityChange(fn) { /** @type {?} */ let record; for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) { fn(record); } } /** * @param {?} collection * @return {?} */ diff(collection) { if (collection == null) collection = []; if (!isListLikeIterable(collection)) { throw new Error(`Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed`); } if (this.check(collection)) { return this; } else { return null; } } /** * @return {?} */ onDestroy() { } /** * @param {?} collection * @return {?} */ check(collection) { this._reset(); /** @type {?} */ let record = this._itHead; /** @type {?} */ let mayBeDirty = false; /** @type {?} */ let index; /** @type {?} */ let item; /** @type {?} */ let itemTrackBy; if (Array.isArray(collection)) { ((/** @type {?} */ (this))).length = collection.length; for (let index = 0; index < this.length; index++) { item = collection[index]; itemTrackBy = this._trackByFn(index, item); if (record === null || !looseIdentical(record.trackById, itemTrackBy)) { record = this._mismatch(record, item, itemTrackBy, index); mayBeDirty = true; } else { if (mayBeDirty) { // TODO(misko): can we limit this to duplicates only? record = this._verifyReinsertion(record, item, itemTrackBy, index); } if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item); } record = record._next; } } else { index = 0; iterateListLike(collection, (/** * @param {?} item * @return {?} */ (item) => { itemTrackBy = this._trackByFn(index, item); if (record === null || !looseIdentical(record.trackById, itemTrackBy)) { record = this._mismatch(record, item, itemTrackBy, index); mayBeDirty = true; } else { if (mayBeDirty) { // TODO(misko): can we limit this to duplicates only? record = this._verifyReinsertion(record, item, itemTrackBy, index); } if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item); } record = record._next; index++; })); ((/** @type {?} */ (this))).length = index; } this._truncate(record); ((/** @type {?} */ (this))).collection = collection; return this.isDirty; } /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity * changes. */ /** * @return {?} */ get isDirty() { return this._additionsHead !== null || this._movesHead !== null || this._removalsHead !== null || this._identityChangesHead !== null; } /** * Reset the state of the change objects to show no changes. This means set previousKey to * currentKey, and clear all of the queues (additions, moves, removals). * Set the previousIndexes of moved and added items to their currentIndexes * Reset the list of additions, moves and removals * * \@internal * @return {?} */ _reset() { if (this.isDirty) { /** @type {?} */ let record; /** @type {?} */ let nextRecord; for (record = this._previousItHead = this._itHead; record !== null; record = record._next) { record._nextPrevious = record._next; } for (record = this._additionsHead; record !== null; record = record._nextAdded) { record.previousIndex = record.currentIndex; } this._additionsHead = this._additionsTail = null; for (record = this._movesHead; record !== null; record = nextRecord) { record.previousIndex = record.currentIndex; nextRecord = record._nextMoved; } this._movesHead = this._movesTail = null; this._removalsHead = this._removalsTail = null; this._identityChangesHead = this._identityChangesTail = null; // TODO(vicb): when assert gets supported // assert(!this.isDirty); } } /** * This is the core function which handles differences between collections. * * - `record` is the record which we saw at this position last time. If null then it is a new * item. * - `item` is the current item in the collection * - `index` is the position of the item in the collection * * \@internal * @param {?} record * @param {?} item * @param {?} itemTrackBy * @param {?} index * @return {?} */ _mismatch(record, item, itemTrackBy, index) { // The previous record after which we will append the current one. /** @type {?} */ let previousRecord; if (record === null) { previousRecord = this._itTail; } else { previousRecord = record._prev; // Remove the record from the collection since we know it does not match the item. this._remove(record); } // Attempt to see if we have seen the item before. record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index); if (record !== null) { // We have seen this before, we need to move it forward in the collection. // But first we need to check if identity changed, so we can update in view if necessary if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item); this._moveAfter(record, previousRecord, index); } else { // Never seen it, check evicted list. record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null); if (record !== null) { // It is an item which we have evicted earlier: reinsert it back into the list. // But first we need to check if identity changed, so we can update in view if necessary if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item); this._reinsertAfter(record, previousRecord, index); } else { // It is a new item: add it. record = this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index); } } return record; } /** * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty) * * Use case: `[a, a]` => `[b, a, a]` * * If we did not have this check then the insertion of `b` would: * 1) evict first `a` * 2) insert `b` at `0` index. * 3) leave `a` at index `1` as is. <-- this is wrong! * 3) reinsert `a` at index 2. <-- this is wrong! * * The correct behavior is: * 1) evict first `a` * 2) insert `b` at `0` index. * 3) reinsert `a` at index 1. * 3) move `a` at from `1` to `2`. * * * Double check that we have not evicted a duplicate item. We need to check if the item type may * have already been removed: * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a' * at the end. * * \@internal * @param {?} record * @param {?} item * @param {?} itemTrackBy * @param {?} index * @return {?} */ _verifyReinsertion(record, item, itemTrackBy, index) { /** @type {?} */ let reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null); if (reinsertRecord !== null) { record = this._reinsertAfter(reinsertRecord, (/** @type {?} */ (record._prev)), index); } else if (record.currentIndex != index) { record.currentIndex = index; this._addToMoves(record, index); } return record; } /** * Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection * * - `record` The first excess {\@link IterableChangeRecord_}. * * \@internal * @param {?} record * @return {?} */ _truncate(record) { // Anything after that needs to be removed; while (record !== null) { /** @type {?} */ const nextRecord = record._next; this._addToRemovals(this._unlink(record)); record = nextRecord; } if (this._unlinkedRecords !== null) { this._unlinkedRecords.clear(); } if (this._additionsTail !== null) { this._additionsTail._nextAdded = null; } if (this._movesTail !== null) { this._movesTail._nextMoved = null; } if (this._itTail !== null) { this._itTail._next = null; } if (this._removalsTail !== null) { this._removalsTail._nextRemoved = null; } if (this._identityChangesTail !== null) { this._identityChangesTail._nextIdentityChange = null; } } /** * \@internal * @param {?} record * @param {?} prevRecord * @param {?} index * @return {?} */ _reinsertAfter(record, prevRecord, index) { if (this._unlinkedRecords !== null) { this._unlinkedRecords.remove(record); } /** @type {?} */ const prev = record._prevRemoved; /** @type {?} */ const next = record._nextRemoved; if (prev === null) { this._removalsHead = next; } else { prev._nextRemoved = next; } if (next === null) { this._removalsTail = prev; } else { next._prevRemoved = prev; } this._insertAfter(record, prevRecord, index); this._addToMoves(record, index); return record; } /** * \@internal * @param {?} record * @param {?} prevRecord * @param {?} index * @return {?} */ _moveAfter(record, prevRecord, index) { this._unlink(record); this._insertAfter(record, prevRecord, index); this._addToMoves(record, index); return record; } /** * \@internal * @param {?} record * @param {?} prevRecord * @param {?} index * @return {?} */ _addAfter(record, prevRecord, index) { this._insertAfter(record, prevRecord, index); if (this._additionsTail === null) { // TODO(vicb): // assert(this._additionsHead === null); this._additionsTail = this._additionsHead = record; } else { // TODO(vicb): // assert(_additionsTail._nextAdded === null); // assert(record._nextAdded === null); this._additionsTail = this._additionsTail._nextAdded = record; } return record; } /** * \@internal * @param {?} record * @param {?} prevRecord * @param {?} index * @return {?} */ _insertAfter(record, prevRecord, index) { // TODO(vicb): // assert(record != prevRecord); // assert(record._next === null); // assert(record._prev === null); // TODO(vicb): // assert(record != prevRecord); // assert(record._next === null); // assert(record._prev === null); /** @type {?} */ const next = prevRecord === null ? this._itHead : prevRecord._next; // TODO(vicb): // assert(next != record); // assert(prevRecord != record); record._next = next; record._prev = prevRecord; if (next === null) { this._itTail = record; } else { next._prev = record; } if (prevRecord === null) { this._itHead = record; } else { prevRecord._next = record; } if (this._linkedRecords === null) { this._linkedRecords = new _DuplicateMap(); } this._linkedRecords.put(record); record.currentIndex = index; return record; } /** * \@internal * @param {?} record * @return {?} */ _remove(record) { return this._addToRemovals(this._unlink(record)); } /** * \@internal * @param {?} record * @return {?} */ _unlink(record) { if (this._linkedRecords !== null) { this._linkedRecords.remove(record); } /** @type {?} */ const prev = record._prev; /** @type {?} */ const next = record._next; // TODO(vicb): // assert((record._prev = null) === null); // assert((record._next = null) === null); if (prev === null) { this._itHead = next; } else { prev._next = next; } if (next === null) { this._itTail = prev; } else { next._prev = prev; } return record; } /** * \@internal * @param {?} record * @param {?} toIndex * @return {?} */ _addToMoves(record, toIndex) { // TODO(vicb): // assert(record._nextMoved === null); if (record.previousIndex === toIndex) { return record; } if (this._movesTail === null) { // TODO(vicb): // assert(_movesHead === null); this._movesTail = this._movesHead = record; } else { // TODO(vicb): // assert(_movesTail._nextMoved === null); this._movesTail = this._movesTail._nextMoved = record; } return record; } /** * @private * @param {?} record * @return {?} */ _addToRemovals(record) { if (this._unlinkedRecords === null) { this._unlinkedRecords = new _DuplicateMap(); } this._unlinkedRecords.put(record); record.currentIndex = null; record._nextRemoved = null; if (this._removalsTail === null) { // TODO(vicb): // assert(_removalsHead === null); this._removalsTail = this._removalsHead = record; record._prevRemoved = null; } else { // TODO(vicb): // assert(_removalsTail._nextRemoved === null); // assert(record._nextRemoved === null); record._prevRemoved = this._removalsTail; this._removalsTail = this._removalsTail._nextRemoved = record; } return record; } /** * \@internal * @param {?} record * @param {?} item * @return {?} */ _addIdentityChange(record, item) { record.item = item; if (this._identityChangesTail === null) { this._identityChangesTail = this._identityChangesHead = record; } else { this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record; } return record; } } if (false) { /** @type {?} */ DefaultIterableDiffer.prototype.length; /** @type {?} */ DefaultIterableDiffer.prototype.collection; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._linkedRecords; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._unlinkedRecords; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._previousItHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._itHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._itTail; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._additionsHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._additionsTail; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._movesHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._movesTail; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._removalsHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._removalsTail; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._identityChangesHead; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._identityChangesTail; /** * @type {?} * @private */ DefaultIterableDiffer.prototype._trackByFn; } /** * @template V */ export class IterableChangeRecord_ { /** * @param {?} item * @param {?} trackById */ constructor(item, trackById) { this.item = item; this.trackById = trackById; this.currentIndex = null; this.previousIndex = null; /** * \@internal */ this._nextPrevious = null; /** * \@internal */ this._prev = null; /** * \@internal */ this._next = null; /** * \@internal */ this._prevDup = null; /** * \@internal */ this._nextDup = null; /** * \@internal */ this._prevRemoved = null; /** * \@internal */ this._nextRemoved = null; /** * \@internal */ this._nextAdded = null; /** * \@internal */ this._nextMoved = null; /** * \@internal */ this._nextIdentityChange = null; } } if (false) { /** @type {?} */ IterableChangeRecord_.prototype.currentIndex; /** @type {?} */ IterableChangeRecord_.prototype.previousIndex; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextPrevious; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._prev; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._next; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._prevDup; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextDup; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._prevRemoved; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextRemoved; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextAdded; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextMoved; /** * \@internal * @type {?} */ IterableChangeRecord_.prototype._nextIdentityChange; /** @type {?} */ IterableChangeRecord_.prototype.item; /** @type {?} */ IterableChangeRecord_.prototype.trackById; } // A linked list of CollectionChangeRecords with the same IterableChangeRecord_.item /** * @template V */ class _DuplicateItemRecordList { constructor() { /** * \@internal */ this._head = null; /** * \@internal */ this._tail = null; } /** * Append the record to the list of duplicates. * * Note: by design all records in the list of duplicates hold the same value in record.item. * @param {?} record * @return {?} */ add(record) { if (this._head === null) { this._head = this._tail = record; record._nextDup = null; record._prevDup = null; } else { // TODO(vicb): // assert(record.item == _head.item || // record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN); (/** @type {?} */ (this._tail))._nextDup = record; record._prevDup = this._tail; record._nextDup = null; this._tail = record; } } // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and // IterableChangeRecord_.currentIndex >= atOrAfterIndex /** * @param {?} trackById * @param {?} atOrAfterIndex * @return {?} */ get(trackById, atOrAfterIndex) { /** @type {?} */ let record; for (record = this._head; record !== null; record = record._nextDup) { if ((atOrAfterIndex === null || atOrAfterIndex <= (/** @type {?} */ (record.currentIndex))) && looseIdentical(record.trackById, trackById)) { return record; } } return null; } /** * Remove one {\@link IterableChangeRecord_} from the list of duplicates. * * Returns whether the list of duplicates is empty. * @param {?} record * @return {?} */ remove(record) { // TODO(vicb): // assert(() { // // verify that the record being removed is in the list. // for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) { // if (identical(cursor, record)) return true; // } // return false; //}); // TODO(vicb): // assert(() { // // verify that the record being removed is in the list. // for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) { // if (identical(cursor, record)) return true; // } // return false; //}); /** @type {?} */ const prev = record._prevDup; /** @type {?} */ const next = record._nextDup; if (prev === null) { this._head = next; } else { prev._nextDup = next; } if (next === null) { this._tail = prev; } else { next._prevDup = prev; } return this._head === null; } } if (false) { /** * \@internal * @type {?} */ _DuplicateItemRecordList.prototype._head; /** * \@internal * @type {?} */ _DuplicateItemRecordList.prototype._tail; } /** * @template V */ class _DuplicateMap { constructor() { this.map = new Map(); } /** * @param {?} record * @return {?} */ put(record) { /** @type {?} */ const key = record.trackById; /** @type {?} */ let duplicates = this.map.get(key); if (!duplicates) { duplicates = new _DuplicateItemRecordList(); this.map.set(key, duplicates); } duplicates.add(record); } /** * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there. * * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we * have any more `a`s needs to return the second `a`. * @param {?} trackById * @param {?} atOrAfterIndex * @return {?} */ get(trackById, atOrAfterIndex) { /** @type {?} */ const key = trackById; /** @type {?} */ const recordList = this.map.get(key); return recordList ? recordList.get(trackById, atOrAfterIndex) : null; } /** * Removes a {\@link IterableChangeRecord_} from the list of duplicates. * * The list of duplicates also is removed from the map if it gets empty. * @param {?} record * @return {?} */ remove(record) { /** @type {?} */ const key = record.trackById; /** @type {?} */ const recordList = (/** @type {?} */ (this.map.get(key))); // Remove the list of duplicates when it gets empty if (recordList.remove(record)) { this.map.delete(key); } return record; } /** * @return {?} */ get isEmpty() { return this.map.size === 0; } /** * @return {?} */ clear() { this.map.clear(); } } if (false) { /** @type {?} */ _DuplicateMap.prototype.map; } /** * @param {?} item * @param {?} addRemoveOffset * @param {?} moveOffsets * @return {?} */ function getPreviousIndex(item, addRemoveOffset, moveOffsets) { /** @type {?} */ const previousIndex = item.previousIndex; if (previousIndex === null) return previousIndex; /** @type {?} */ let moveOffset = 0; if (moveOffsets && previousIndex < moveOffsets.length) { moveOffset = moveOffsets[previousIndex]; } return previousIndex + addRemoveOffset + moveOffset; } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9pdGVyYWJsZV9kaWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9jaGFuZ2VfZGV0ZWN0aW9uL2RpZmZlcnMvZGVmYXVsdF9pdGVyYWJsZV9kaWZmZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxlQUFlLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUs3RSxNQUFNLE9BQU8sNEJBQTRCO0lBQ3ZDLGdCQUFlLENBQUM7Ozs7O0lBQ2hCLFFBQVEsQ0FBQyxHQUEwQixJQUFhLE9BQU8sa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7Ozs7SUFFakYsTUFBTSxDQUFJLFNBQThCO1FBQ3RDLE9BQU8sSUFBSSxxQkFBcUIsQ0FBSSxTQUFTLENBQUMsQ0FBQztJQUNqRCxDQUFDO0NBQ0Y7O01BRUssZUFBZTs7Ozs7QUFBRyxDQUFDLEtBQWEsRUFBRSxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQTs7Ozs7OztBQU0xRCxNQUFNLE9BQU8scUJBQXFCOzs7O0lBc0JoQyxZQUFZLFNBQThCO1FBckIxQixXQUFNLEdBQVcsQ0FBQyxDQUFDOztRQUkzQixtQkFBYyxHQUEwQixJQUFJLENBQUM7O1FBRTdDLHFCQUFnQixHQUEwQixJQUFJLENBQUM7UUFDL0Msb0JBQWUsR0FBa0MsSUFBSSxDQUFDO1FBQ3RELFlBQU8sR0FBa0MsSUFBSSxDQUFDO1FBQzlDLFlBQU8sR0FBa0MsSUFBSSxDQUFDO1FBQzlDLG1CQUFjLEdBQWtDLElBQUksQ0FBQztRQUNyRCxtQkFBYyxHQUFrQyxJQUFJLENBQUM7UUFDckQsZUFBVSxHQUFr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