UNPKG

@data-client/core

Version:

Async State Management without the Management. REST, GraphQL, SSE, Websockets, Fetch

162 lines (160 loc) 19.6 kB
import { GC } from '../actionTypes.js'; export class GCPolicy { constructor({ // every 5 min intervalMS = 60 * 1000 * 5, expiryMultiplier = 2, expiresAt } = {}) { this.endpointCount = new Map(); this.entityCount = new Map(); this.endpointsQ = new Set(); this.entitiesQ = []; if (expiresAt) { this.expiresAt = expiresAt.bind(this); } this.options = { intervalMS, expiryMultiplier }; } init(controller) { this.controller = controller; this.intervalId = setInterval(() => { this.idleCallback(() => this.runSweep(), { timeout: 1000 }); }, this.options.intervalMS); if (typeof this.intervalId === 'object' && 'unref' in this.intervalId) { this.intervalId.unref(); } } cleanup() { clearInterval(this.intervalId); } createCountRef({ key, paths = [] }) { // increment return () => { var _this$endpointCount$g; if (key) this.endpointCount.set(key, ((_this$endpointCount$g = this.endpointCount.get(key)) != null ? _this$endpointCount$g : 0) + 1); paths.forEach(path => { var _instanceCount$get; const { key, pk } = path; if (!this.entityCount.has(key)) { this.entityCount.set(key, new Map()); } const instanceCount = this.entityCount.get(key); instanceCount.set(pk, ((_instanceCount$get = instanceCount.get(pk)) != null ? _instanceCount$get : 0) + 1); }); // decrement return () => { if (key) { const currentCount = this.endpointCount.get(key); if (currentCount !== undefined) { if (currentCount <= 1) { this.endpointCount.delete(key); // queue for cleanup this.endpointsQ.add(key); } else { this.endpointCount.set(key, currentCount - 1); } } } paths.forEach(path => { const { key, pk } = path; if (!this.entityCount.has(key)) { return; } const instanceCount = this.entityCount.get(key); const entityCount = instanceCount.get(pk); if (entityCount !== undefined) { if (entityCount <= 1) { instanceCount.delete(pk); // queue for cleanup this.entitiesQ.push(path); } else { instanceCount.set(pk, entityCount - 1); } } }); }; }; } expiresAt({ fetchedAt, expiresAt }) { return Math.max((expiresAt - fetchedAt) * this.options.expiryMultiplier, 120000) + fetchedAt; } runSweep() { const state = this.controller.getState(); const entities = []; const endpoints = []; const now = Date.now(); const nextEndpointsQ = new Set(); for (const key of this.endpointsQ) { var _state$meta$key; if (!this.endpointCount.has(key) && this.expiresAt((_state$meta$key = state.meta[key]) != null ? _state$meta$key : { fetchedAt: 0, date: 0, expiresAt: 0 }) < now) { endpoints.push(key); } else { nextEndpointsQ.add(key); } } this.endpointsQ = nextEndpointsQ; const nextEntitiesQ = []; for (const path of this.entitiesQ) { var _this$entityCount$get, _state$entitiesMeta$p, _state$entitiesMeta$p2; if (!((_this$entityCount$get = this.entityCount.get(path.key)) != null && _this$entityCount$get.has(path.pk)) && this.expiresAt((_state$entitiesMeta$p = (_state$entitiesMeta$p2 = state.entitiesMeta[path.key]) == null ? void 0 : _state$entitiesMeta$p2[path.pk]) != null ? _state$entitiesMeta$p : { fetchedAt: 0, date: 0, expiresAt: 0 }) < now) { entities.push(path); } else { nextEntitiesQ.push(path); } } this.entitiesQ = nextEntitiesQ; if (entities.length || endpoints.length) { this.controller.dispatch({ type: GC, entities, endpoints }); } } /** Calls the callback when client is not 'busy' with high priority interaction tasks * * Override for platform-specific implementations */ idleCallback(callback, options) { if (typeof requestIdleCallback === 'function') { requestIdleCallback(callback, options); } else { callback(); } } } export class ImmortalGCPolicy { // eslint-disable-next-line @typescript-eslint/no-empty-function init() {} // eslint-disable-next-line @typescript-eslint/no-empty-function cleanup() {} createCountRef() { return () => () => undefined; } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJHQyIsIkdDUG9saWN5IiwiY29uc3RydWN0b3IiLCJpbnRlcnZhbE1TIiwiZXhwaXJ5TXVsdGlwbGllciIsImV4cGlyZXNBdCIsImVuZHBvaW50Q291bnQiLCJNYXAiLCJlbnRpdHlDb3VudCIsImVuZHBvaW50c1EiLCJTZXQiLCJlbnRpdGllc1EiLCJiaW5kIiwib3B0aW9ucyIsImluaXQiLCJjb250cm9sbGVyIiwiaW50ZXJ2YWxJZCIsInNldEludGVydmFsIiwiaWRsZUNhbGxiYWNrIiwicnVuU3dlZXAiLCJ0aW1lb3V0IiwidW5yZWYiLCJjbGVhbnVwIiwiY2xlYXJJbnRlcnZhbCIsImNyZWF0ZUNvdW50UmVmIiwia2V5IiwicGF0aHMiLCJfdGhpcyRlbmRwb2ludENvdW50JGciLCJzZXQiLCJnZXQiLCJmb3JFYWNoIiwicGF0aCIsIl9pbnN0YW5jZUNvdW50JGdldCIsInBrIiwiaGFzIiwiaW5zdGFuY2VDb3VudCIsImN1cnJlbnRDb3VudCIsInVuZGVmaW5lZCIsImRlbGV0ZSIsImFkZCIsInB1c2giLCJmZXRjaGVkQXQiLCJNYXRoIiwibWF4Iiwic3RhdGUiLCJnZXRTdGF0ZSIsImVudGl0aWVzIiwiZW5kcG9pbnRzIiwibm93IiwiRGF0ZSIsIm5leHRFbmRwb2ludHNRIiwiX3N0YXRlJG1ldGEka2V5IiwibWV0YSIsImRhdGUiLCJuZXh0RW50aXRpZXNRIiwiX3RoaXMkZW50aXR5Q291bnQkZ2V0IiwiX3N0YXRlJGVudGl0aWVzTWV0YSRwIiwiX3N0YXRlJGVudGl0aWVzTWV0YSRwMiIsImVudGl0aWVzTWV0YSIsImxlbmd0aCIsImRpc3BhdGNoIiwidHlwZSIsImNhbGxiYWNrIiwicmVxdWVzdElkbGVDYWxsYmFjayIsIkltbW9ydGFsR0NQb2xpY3kiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGUvR0NQb2xpY3kudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBFbnRpdHlQYXRoIH0gZnJvbSAnQGRhdGEtY2xpZW50L25vcm1hbGl6cic7XG5cbmltcG9ydCB7IEdDIH0gZnJvbSAnLi4vYWN0aW9uVHlwZXMuanMnO1xuaW1wb3J0IENvbnRyb2xsZXIgZnJvbSAnLi4vY29udHJvbGxlci9Db250cm9sbGVyLmpzJztcblxuZXhwb3J0IGNsYXNzIEdDUG9saWN5IGltcGxlbWVudHMgR0NJbnRlcmZhY2Uge1xuICBwcm90ZWN0ZWQgZW5kcG9pbnRDb3VudCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByb3RlY3RlZCBlbnRpdHlDb3VudCA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXI+PigpO1xuICBwcm90ZWN0ZWQgZW5kcG9pbnRzUSA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcm90ZWN0ZWQgZW50aXRpZXNROiBFbnRpdHlQYXRoW10gPSBbXTtcblxuICBkZWNsYXJlIHByb3RlY3RlZCBpbnRlcnZhbElkOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD47XG4gIGRlY2xhcmUgcHJvdGVjdGVkIGNvbnRyb2xsZXI6IENvbnRyb2xsZXI7XG4gIGRlY2xhcmUgcHJvdGVjdGVkIG9wdGlvbnM6IFJlcXVpcmVkPE9taXQ8R0NPcHRpb25zLCAnZXhwaXJlc0F0Jz4+O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICAvLyBldmVyeSA1IG1pblxuICAgIGludGVydmFsTVMgPSA2MCAqIDEwMDAgKiA1LFxuICAgIGV4cGlyeU11bHRpcGxpZXIgPSAyLFxuICAgIGV4cGlyZXNBdCxcbiAgfTogR0NPcHRpb25zID0ge30pIHtcbiAgICBpZiAoZXhwaXJlc0F0KSB7XG4gICAgICB0aGlzLmV4cGlyZXNBdCA9IGV4cGlyZXNBdC5iaW5kKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBpbnRlcnZhbE1TLFxuICAgICAgZXhwaXJ5TXVsdGlwbGllcixcbiAgICB9O1xuICB9XG5cbiAgaW5pdChjb250cm9sbGVyOiBDb250cm9sbGVyKSB7XG4gICAgdGhpcy5jb250cm9sbGVyID0gY29udHJvbGxlcjtcblxuICAgIHRoaXMuaW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHRoaXMuaWRsZUNhbGxiYWNrKCgpID0+IHRoaXMucnVuU3dlZXAoKSwgeyB0aW1lb3V0OiAxMDAwIH0pO1xuICAgIH0sIHRoaXMub3B0aW9ucy5pbnRlcnZhbE1TKTtcbiAgICBpZiAodHlwZW9mIHRoaXMuaW50ZXJ2YWxJZCA9PT0gJ29iamVjdCcgJiYgJ3VucmVmJyBpbiB0aGlzLmludGVydmFsSWQpIHtcbiAgICAgIHRoaXMuaW50ZXJ2YWxJZC51bnJlZigpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFudXAoKSB7XG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLmludGVydmFsSWQpO1xuICB9XG5cbiAgY3JlYXRlQ291bnRSZWYoeyBrZXksIHBhdGhzID0gW10gfTogeyBrZXk/OiBzdHJpbmc7IHBhdGhzPzogRW50aXR5UGF0aFtdIH0pIHtcbiAgICAvLyBpbmNyZW1lbnRcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgaWYgKGtleSlcbiAgICAgICAgdGhpcy5lbmRwb2ludENvdW50LnNldChrZXksICh0aGlzLmVuZHBvaW50Q291bnQuZ2V0KGtleSkgPz8gMCkgKyAxKTtcbiAgICAgIHBhdGhzLmZvckVhY2gocGF0aCA9PiB7XG4gICAgICAgIGNvbnN0IHsga2V5LCBwayB9ID0gcGF0aDtcbiAgICAgICAgaWYgKCF0aGlzLmVudGl0eUNvdW50LmhhcyhrZXkpKSB7XG4gICAgICAgICAgdGhpcy5lbnRpdHlDb3VudC5zZXQoa2V5LCBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnN0YW5jZUNvdW50ID0gdGhpcy5lbnRpdHlDb3VudC5nZXQoa2V5KSE7XG4gICAgICAgIGluc3RhbmNlQ291bnQuc2V0KHBrLCAoaW5zdGFuY2VDb3VudC5nZXQocGspID8/IDApICsgMSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gZGVjcmVtZW50XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudENvdW50ID0gdGhpcy5lbmRwb2ludENvdW50LmdldChrZXkpITtcbiAgICAgICAgICBpZiAoY3VycmVudENvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50Q291bnQgPD0gMSkge1xuICAgICAgICAgICAgICB0aGlzLmVuZHBvaW50Q291bnQuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICAgIC8vIHF1ZXVlIGZvciBjbGVhbnVwXG4gICAgICAgICAgICAgIHRoaXMuZW5kcG9pbnRzUS5hZGQoa2V5KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuZW5kcG9pbnRDb3VudC5zZXQoa2V5LCBjdXJyZW50Q291bnQgLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcGF0aHMuZm9yRWFjaChwYXRoID0+IHtcbiAgICAgICAgICBjb25zdCB7IGtleSwgcGsgfSA9IHBhdGg7XG4gICAgICAgICAgaWYgKCF0aGlzLmVudGl0eUNvdW50LmhhcyhrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGluc3RhbmNlQ291bnQgPSB0aGlzLmVudGl0eUNvdW50LmdldChrZXkpITtcbiAgICAgICAgICBjb25zdCBlbnRpdHlDb3VudCA9IGluc3RhbmNlQ291bnQuZ2V0KHBrKSE7XG4gICAgICAgICAgaWYgKGVudGl0eUNvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChlbnRpdHlDb3VudCA8PSAxKSB7XG4gICAgICAgICAgICAgIGluc3RhbmNlQ291bnQuZGVsZXRlKHBrKTtcbiAgICAgICAgICAgICAgLy8gcXVldWUgZm9yIGNsZWFudXBcbiAgICAgICAgICAgICAgdGhpcy5lbnRpdGllc1EucHVzaChwYXRoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGluc3RhbmNlQ291bnQuc2V0KHBrLCBlbnRpdHlDb3VudCAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgZXhwaXJlc0F0KHtcbiAgICBmZXRjaGVkQXQsXG4gICAgZXhwaXJlc0F0LFxuICB9OiB7XG4gICAgZXhwaXJlc0F0OiBudW1iZXI7XG4gICAgZGF0ZTogbnVtYmVyO1xuICAgIGZldGNoZWRBdDogbnVtYmVyO1xuICB9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgTWF0aC5tYXgoXG4gICAgICAgIChleHBpcmVzQXQgLSBmZXRjaGVkQXQpICogdGhpcy5vcHRpb25zLmV4cGlyeU11bHRpcGxpZXIsXG4gICAgICAgIDEyMDAwMCxcbiAgICAgICkgKyBmZXRjaGVkQXRcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJ1blN3ZWVwKCkge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5jb250cm9sbGVyLmdldFN0YXRlKCk7XG4gICAgY29uc3QgZW50aXRpZXM6IEVudGl0eVBhdGhbXSA9IFtdO1xuICAgIGNvbnN0IGVuZHBvaW50czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgY29uc3QgbmV4dEVuZHBvaW50c1EgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiB0aGlzLmVuZHBvaW50c1EpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuZW5kcG9pbnRDb3VudC5oYXMoa2V5KSAmJlxuICAgICAgICB0aGlzLmV4cGlyZXNBdChcbiAgICAgICAgICBzdGF0ZS5tZXRhW2tleV0gPz8ge1xuICAgICAgICAgICAgZmV0Y2hlZEF0OiAwLFxuICAgICAgICAgICAgZGF0ZTogMCxcbiAgICAgICAgICAgIGV4cGlyZXNBdDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICApIDwgbm93XG4gICAgICApIHtcbiAgICAgICAgZW5kcG9pbnRzLnB1c2goa2V5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRFbmRwb2ludHNRLmFkZChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmVuZHBvaW50c1EgPSBuZXh0RW5kcG9pbnRzUTtcblxuICAgIGNvbnN0IG5leHRFbnRpdGllc1E6IEVudGl0eVBhdGhbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcGF0aCBvZiB0aGlzLmVudGl0aWVzUSkge1xuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5lbnRpdHlDb3VudC5nZXQocGF0aC5rZXkpPy5oYXMocGF0aC5waykgJiZcbiAgICAgICAgdGhpcy5leHBpcmVzQXQoXG4gICAgICAgICAgc3RhdGUuZW50aXRpZXNNZXRhW3BhdGgua2V5XT8uW3BhdGgucGtdID8/IHtcbiAgICAgICAgICAgIGZldGNoZWRBdDogMCxcbiAgICAgICAgICAgIGRhdGU6IDAsXG4gICAgICAgICAgICBleHBpcmVzQXQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA8IG5vd1xuICAgICAgKSB7XG4gICAgICAgIGVudGl0aWVzLnB1c2gocGF0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0RW50aXRpZXNRLnB1c2gocGF0aCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZW50aXRpZXNRID0gbmV4dEVudGl0aWVzUTtcblxuICAgIGlmIChlbnRpdGllcy5sZW5ndGggfHwgZW5kcG9pbnRzLmxlbmd0aCkge1xuICAgICAgdGhpcy5jb250cm9sbGVyLmRpc3BhdGNoKHsgdHlwZTogR0MsIGVudGl0aWVzLCBlbmRwb2ludHMgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENhbGxzIHRoZSBjYWxsYmFjayB3aGVuIGNsaWVudCBpcyBub3QgJ2J1c3knIHdpdGggaGlnaCBwcmlvcml0eSBpbnRlcmFjdGlvbiB0YXNrc1xuICAgKlxuICAgKiBPdmVycmlkZSBmb3IgcGxhdGZvcm0tc3BlY2lmaWMgaW1wbGVtZW50YXRpb25zXG4gICAqL1xuICBwcm90ZWN0ZWQgaWRsZUNhbGxiYWNrKFxuICAgIGNhbGxiYWNrOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQsXG4gICAgb3B0aW9ucz86IElkbGVSZXF1ZXN0T3B0aW9ucyxcbiAgKSB7XG4gICAgaWYgKHR5cGVvZiByZXF1ZXN0SWRsZUNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXF1ZXN0SWRsZUNhbGxiYWNrKGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEltbW9ydGFsR0NQb2xpY3kgaW1wbGVtZW50cyBHQ0ludGVyZmFjZSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgaW5pdCgpIHt9XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgY2xlYW51cCgpIHt9XG4gIGNyZWF0ZUNvdW50UmVmKCkge1xuICAgIHJldHVybiAoKSA9PiAoKSA9PiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBHQ09wdGlvbnMge1xuICBpbnRlcnZhbE1TPzogbnVtYmVyO1xuICBleHBpcnlNdWx0aXBsaWVyPzogbnVtYmVyO1xuICBleHBpcmVzQXQ/OiAobWV0YToge1xuICAgIGV4cGlyZXNBdDogbnVtYmVyO1xuICAgIGRhdGU6IG51bWJlcjtcbiAgICBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgfSkgPT4gbnVtYmVyO1xufVxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVDb3VudFJlZiB7XG4gICh7IGtleSwgcGF0aHMgfTogeyBrZXk/OiBzdHJpbmc7IHBhdGhzPzogRW50aXR5UGF0aFtdIH0pOiAoKSA9PiAoKSA9PiB2b2lkO1xufVxuZXhwb3J0IGludGVyZmFjZSBHQ0ludGVyZmFjZSB7XG4gIGNyZWF0ZUNvdW50UmVmOiBDcmVhdGVDb3VudFJlZjtcbiAgaW5pdChjb250cm9sbGVyOiBDb250cm9sbGVyKTogdm9pZDtcbiAgY2xlYW51cCgpOiB2b2lkO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFFQSxTQUFTQSxFQUFFLFFBQVEsbUJBQW1CO0FBR3RDLE9BQU8sTUFBTUMsUUFBUSxDQUF3QjtFQVUzQ0MsV0FBV0EsQ0FBQztJQUNWO0lBQ0FDLFVBQVUsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDMUJDLGdCQUFnQixHQUFHLENBQUM7SUFDcEJDO0VBQ1MsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO0lBQUEsS0FkVEMsYUFBYSxHQUFHLElBQUlDLEdBQUcsQ0FBaUIsQ0FBQztJQUFBLEtBQ3pDQyxXQUFXLEdBQUcsSUFBSUQsR0FBRyxDQUE4QixDQUFDO0lBQUEsS0FDcERFLFVBQVUsR0FBRyxJQUFJQyxHQUFHLENBQVMsQ0FBQztJQUFBLEtBQzlCQyxTQUFTLEdBQWlCLEVBQUU7SUFZcEMsSUFBSU4sU0FBUyxFQUFFO01BQ2IsSUFBSSxDQUFDQSxTQUFTLEdBQUdBLFNBQVMsQ0FBQ08sSUFBSSxDQUFDLElBQUksQ0FBQztJQUN2QztJQUNBLElBQUksQ0FBQ0MsT0FBTyxHQUFHO01BQ2JWLFVBQVU7TUFDVkM7SUFDRixDQUFDO0VBQ0g7RUFFQVUsSUFBSUEsQ0FBQ0MsVUFBc0IsRUFBRTtJQUMzQixJQUFJLENBQUNBLFVBQVUsR0FBR0EsVUFBVTtJQUU1QixJQUFJLENBQUNDLFVBQVUsR0FBR0MsV0FBVyxDQUFDLE1BQU07TUFDbEMsSUFBSSxDQUFDQyxZQUFZLENBQUMsTUFBTSxJQUFJLENBQUNDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7UUFBRUMsT0FBTyxFQUFFO01BQUssQ0FBQyxDQUFDO0lBQzdELENBQUMsRUFBRSxJQUFJLENBQUNQLE9BQU8sQ0FBQ1YsVUFBVSxDQUFDO0lBQzNCLElBQUks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