{
  "version": 3,
  "sources": ["lru.js"],
  "sourcesContent": ["/**\n * A doubly linked list-based Least Recently Used (LRU) cache. Will keep most\n * recently used items while discarding least recently used items when its limit\n * is reached.\n *\n * Licensed under MIT. Copyright (c) 2010 Rasmus Andersson <http://hunch.se/>\n * See README.md for details.\n *\n * Illustration of the design:\n *\n *       entry             entry             entry             entry\n *       ______            ______            ______            ______\n *      | head |.newer => |      |.newer => |      |.newer => | tail |\n *      |  A   |          |  B   |          |  C   |          |  D   |\n *      |______| <= older.|______| <= older.|______| <= older.|______|\n *\n *  removed  <--  <--  <--  <--  <--  <--  <--  <--  <--  <--  <--  added\n */\n!function(g,f){\n  if (typeof exports == 'object' && typeof module != \"undefined\") {\n    f(exports)\n  } else if (typeof define == 'function' && define.amd) {\n    define([\"exports\"], f)\n  } else {\n    f((g = g || self)[\"lru_map\"] = (g[\"lru_map\"] || {}))\n  }\n}(this, function(exports) {\n\nconst NEWER = Symbol('newer');\nconst OLDER = Symbol('older');\n\nclass LRUMap {\n  constructor(limit, entries) {\n    if (typeof limit !== 'number') {\n      // called as (entries)\n      entries = limit;\n      limit = 0;\n    }\n\n    this.size = 0;\n    this.limit = limit;\n    this.oldest = this.newest = undefined;\n    this._keymap = new Map();\n\n    if (entries) {\n      this.assign(entries);\n      if (limit < 1) {\n        this.limit = this.size;\n      }\n    }\n  }\n\n  _markEntryAsUsed(entry) {\n    if (entry === this.newest) {\n      // Already the most recenlty used entry, so no need to update the list\n      return;\n    }\n    // HEAD--------------TAIL\n    //   <.older   .newer>\n    //  <--- add direction --\n    //   A  B  C  <D>  E\n    if (entry[NEWER]) {\n      if (entry === this.oldest) {\n        this.oldest = entry[NEWER];\n      }\n      entry[NEWER][OLDER] = entry[OLDER]; // C <-- E.\n    }\n    if (entry[OLDER]) {\n      entry[OLDER][NEWER] = entry[NEWER]; // C. --> E\n    }\n    entry[NEWER] = undefined; // D --x\n    entry[OLDER] = this.newest; // D. --> E\n    if (this.newest) {\n      this.newest[NEWER] = entry; // E. <-- D\n    }\n    this.newest = entry;\n  }\n\n  assign(entries) {\n    let entry, limit = this.limit || Number.MAX_VALUE;\n    this._keymap.clear();\n    let it = entries[Symbol.iterator]();\n    for (let itv = it.next(); !itv.done; itv = it.next()) {\n      let e = new Entry(itv.value[0], itv.value[1]);\n      this._keymap.set(e.key, e);\n      if (!entry) {\n        this.oldest = e;\n      } else {\n        entry[NEWER] = e;\n        e[OLDER] = entry;\n      }\n      entry = e;\n      if (limit-- == 0) {\n        throw new Error('overflow');\n      }\n    }\n    this.newest = entry;\n    this.size = this._keymap.size;\n  }\n\n  get(key) {\n    // First, find our cache entry\n    var entry = this._keymap.get(key);\n    if (!entry) return; // Not cached. Sorry.\n    // As <key> was found in the cache, register it as being requested recently\n    this._markEntryAsUsed(entry);\n    return entry.value;\n  }\n\n  set(key, value) {\n    var entry = this._keymap.get(key);\n\n    if (entry) {\n      // update existing\n      entry.value = value;\n      this._markEntryAsUsed(entry);\n      return this;\n    }\n\n    // new entry\n    this._keymap.set(key, (entry = new Entry(key, value)));\n\n    if (this.newest) {\n      // link previous tail to the new tail (entry)\n      this.newest[NEWER] = entry;\n      entry[OLDER] = this.newest;\n    } else {\n      // we're first in -- yay\n      this.oldest = entry;\n    }\n\n    // add new entry to the end of the linked list -- it's now the freshest entry.\n    this.newest = entry;\n    ++this.size;\n    if (this.size > this.limit) {\n      // we hit the limit -- remove the head\n      this.shift();\n    }\n\n    return this;\n  }\n\n  shift() {\n    // todo: handle special case when limit == 1\n    var entry = this.oldest;\n    if (entry) {\n      if (this.oldest[NEWER]) {\n        // advance the list\n        this.oldest = this.oldest[NEWER];\n        this.oldest[OLDER] = undefined;\n      } else {\n        // the cache is exhausted\n        this.oldest = undefined;\n        this.newest = undefined;\n      }\n      // Remove last strong reference to <entry> and remove links from the purged\n      // entry being returned:\n      entry[NEWER] = entry[OLDER] = undefined;\n      this._keymap.delete(entry.key);\n      --this.size;\n      return [entry.key, entry.value];\n    }\n  }\n\n  // -------------------------------------------------------------------------------------\n  // Following code (until end of class definition) is optional and can be removed without\n  // breaking the core functionality.\n\n  find(key) {\n    let e = this._keymap.get(key);\n    return e ? e.value : undefined;\n  }\n\n  has(key) {\n    return this._keymap.has(key);\n  }\n\n  delete(key) {\n    var entry = this._keymap.get(key);\n    if (!entry) return;\n    this._keymap.delete(entry.key);\n    if (entry[NEWER] && entry[OLDER]) {\n      // relink the older entry with the newer entry\n      entry[OLDER][NEWER] = entry[NEWER];\n      entry[NEWER][OLDER] = entry[OLDER];\n    } else if (entry[NEWER]) {\n      // remove the link to us\n      entry[NEWER][OLDER] = undefined;\n      // link the newer entry to head\n      this.oldest = entry[NEWER];\n    } else if (entry[OLDER]) {\n      // remove the link to us\n      entry[OLDER][NEWER] = undefined;\n      // link the newer entry to head\n      this.newest = entry[OLDER];\n    } else {// if(entry[OLDER] === undefined && entry.newer === undefined) {\n      this.oldest = this.newest = undefined;\n    }\n\n    this.size--;\n    return entry.value;\n  }\n\n  clear() {\n    // Not clearing links should be safe, as we don't expose live links to user\n    this.oldest = this.newest = undefined;\n    this.size = 0;\n    this._keymap.clear();\n  }\n\n  keys() {\n    return new KeyIterator(this.oldest);\n  }\n\n  values() {\n    return new ValueIterator(this.oldest);\n  }\n\n  entries() {\n    return this;\n  }\n\n  [Symbol.iterator]() {\n    return new EntryIterator(this.oldest);\n  }\n\n  forEach(fun, thisObj) {\n    if (typeof thisObj !== 'object') {\n      thisObj = this;\n    }\n    let entry = this.oldest;\n    while (entry) {\n      fun.call(thisObj, entry.value, entry.key, this);\n      entry = entry[NEWER];\n    }\n  }\n\n  /** Returns a JSON (array) representation */\n  toJSON() {\n    var s = new Array(this.size), i = 0, entry = this.oldest;\n    while (entry) {\n      s[i++] = { key: entry.key, value: entry.value };\n      entry = entry[NEWER];\n    }\n    return s;\n  }\n\n  /** Returns a String representation */\n  toString() {\n    var s = '', entry = this.oldest;\n    while (entry) {\n      s += String(entry.key)+':'+entry.value;\n      entry = entry[NEWER];\n      if (entry) {\n        s += ' < ';\n      }\n    }\n    return s;\n  }\n}\n\nexports.LRUMap = LRUMap\n\nfunction Entry(key, value) {\n  this.key = key;\n  this.value = value;\n  this[NEWER] = undefined;\n  this[OLDER] = undefined;\n}\n\n\nfunction EntryIterator(oldestEntry) { this.entry = oldestEntry; }\nEntryIterator.prototype[Symbol.iterator] = function() { return this; }\nEntryIterator.prototype.next = function() {\n  let ent = this.entry;\n  if (ent) {\n    this.entry = ent[NEWER];\n    return { done: false, value: [ent.key, ent.value] };\n  } else {\n    return { done: true, value: undefined };\n  }\n};\n\n\nfunction KeyIterator(oldestEntry) { this.entry = oldestEntry; }\nKeyIterator.prototype[Symbol.iterator] = function() { return this; }\nKeyIterator.prototype.next = function() {\n  let ent = this.entry;\n  if (ent) {\n    this.entry = ent[NEWER];\n    return { done: false, value: ent.key };\n  } else {\n    return { done: true, value: undefined };\n  }\n};\n\nfunction ValueIterator(oldestEntry) { this.entry = oldestEntry; }\nValueIterator.prototype[Symbol.iterator] = function() { return this; }\nValueIterator.prototype.next = function() {\n  let ent = this.entry;\n  if (ent) {\n    this.entry = ent[NEWER];\n    return { done: false, value: ent.value };\n  } else {\n    return { done: true, value: undefined };\n  }\n};\n\n});\n"],
  "mappings": "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",
  "names": []
}
