{"action":"created","comment":{"url":"https://api.github.com/repos/adesege/HelloBooks/pulls/comments/156731732","pull_request_review_id":83258002,"id":156731732,"diff_hunk":"@@ -0,0 +1,1910 @@\n+/**\n+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7\n+ * Copyright (C) 2014 Oliver Nightingale\n+ * MIT Licensed\n+ * @license\n+ */\n+\n+(function(){\n+\n+  /**\n+   * Convenience function for instantiating a new lunr index and configuring it\n+   * with the default pipeline functions and the passed config function.\n+   *\n+   * When using this convenience function a new index will be created with the\n+   * following functions already in the pipeline:\n+   *\n+   * lunr.StopWordFilter - filters out any stop words before they enter the\n+   * index\n+   *\n+   * lunr.stemmer - stems the tokens before entering the index.\n+   *\n+   * Example:\n+   *\n+   *     var idx = lunr(function () {\n+ *       this.field('title', 10)\n+ *       this.field('tags', 100)\n+ *       this.field('body')\n+ *\n+ *       this.ref('cid')\n+ *\n+ *       this.pipeline.add(function () {\n+ *         // some custom pipeline function\n+ *       })\n+ *\n+ *     })\n+   *\n+   * @param {Function} config A function that will be called with the new instance\n+   * of the lunr.Index as both its context and first parameter. It can be used to\n+   * customize the instance of new lunr.Index.\n+   * @namespace\n+   * @module\n+   * @returns {lunr.Index}\n+   *\n+   */\n+  var lunr = function (config) {\n+    var idx = new lunr.Index\n+\n+    idx.pipeline.add(\n+        lunr.trimmer,\n+        lunr.stopWordFilter,\n+        lunr.stemmer\n+    )\n+\n+    if (config) config.call(idx, idx)\n+\n+    return idx\n+  }\n+\n+  lunr.version = \"0.5.7\"\n+  /*!\n+   * lunr.utils\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * A namespace containing utils for the rest of the lunr library\n+   */\n+  lunr.utils = {}\n+\n+  /**\n+   * Print a warning message to the console.\n+   *\n+   * @param {String} message The message to be printed.\n+   * @memberOf Utils\n+   */\n+  lunr.utils.warn = (function (global) {\n+    return function (message) {\n+      if (global.console && console.warn) {\n+        console.warn(message)\n+      }\n+    }\n+  })(this)\n+\n+  /*!\n+   * lunr.EventEmitter\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.EventEmitter is an event emitter for lunr. It manages adding and removing event handlers and triggering events and their handlers.\n+   *\n+   * @constructor\n+   */\n+  lunr.EventEmitter = function () {\n+    this.events = {}\n+  }\n+\n+  /**\n+   * Binds a handler function to a specific event(s).\n+   *\n+   * Can bind a single function to many different events in one call.\n+   *\n+   * @param {String} [eventName] The name(s) of events to bind this function to.\n+   * @param {Function} handler The function to call when an event is fired.\n+   * @memberOf EventEmitter\n+   */\n+  lunr.EventEmitter.prototype.addListener = function () {\n+    var args = Array.prototype.slice.call(arguments),\n+        fn = args.pop(),\n+        names = args\n+\n+    if (typeof fn !== \"function\") throw new TypeError (\"last argument must be a function\")\n+\n+    names.forEach(function (name) {\n+      if (!this.hasHandler(name)) this.events[name] = []\n+      this.events[name].push(fn)\n+    }, this)\n+  }\n+\n+  /**\n+   * Removes a handler function from a specific event.\n+   *\n+   * @param {String} eventName The name of the event to remove this function from.\n+   * @param {Function} handler The function to remove from an event.\n+   * @memberOf EventEmitter\n+   */\n+  lunr.EventEmitter.prototype.removeListener = function (name, fn) {\n+    if (!this.hasHandler(name)) return\n+\n+    var fnIndex = this.events[name].indexOf(fn)\n+    this.events[name].splice(fnIndex, 1)\n+\n+    if (!this.events[name].length) delete this.events[name]\n+  }\n+\n+  /**\n+   * Calls all functions bound to the given event.\n+   *\n+   * Additional data can be passed to the event handler as arguments to `emit`\n+   * after the event name.\n+   *\n+   * @param {String} eventName The name of the event to emit.\n+   * @memberOf EventEmitter\n+   */\n+  lunr.EventEmitter.prototype.emit = function (name) {\n+    if (!this.hasHandler(name)) return\n+\n+    var args = Array.prototype.slice.call(arguments, 1)\n+\n+    this.events[name].forEach(function (fn) {\n+      fn.apply(undefined, args)\n+    })\n+  }\n+\n+  /**\n+   * Checks whether a handler has ever been stored against an event.\n+   *\n+   * @param {String} eventName The name of the event to check.\n+   * @private\n+   * @memberOf EventEmitter\n+   */\n+  lunr.EventEmitter.prototype.hasHandler = function (name) {\n+    return name in this.events\n+  }\n+\n+  /*!\n+   * lunr.tokenizer\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * A function for splitting a string into tokens ready to be inserted into\n+   * the search index.\n+   *\n+   * @module\n+   * @param {String} obj The string to convert into tokens\n+   * @returns {Array}\n+   */\n+  lunr.tokenizer = function (obj) {\n+    if (!arguments.length || obj == null || obj == undefined) return []\n+    if (Array.isArray(obj)) return obj.map(function (t) { return t.toLowerCase() })\n+\n+    var str = obj.toString().replace(/^\\s+/, '')\n+\n+    for (var i = str.length - 1; i >= 0; i--) {\n+      if (/\\S/.test(str.charAt(i))) {\n+        str = str.substring(0, i + 1)\n+        break\n+      }\n+    }\n+\n+    return str\n+        .split(/(?:\\s+|\\-)/)\n+        .filter(function (token) {\n+          return !!token\n+        })\n+        .map(function (token) {\n+          return token.toLowerCase()\n+        })\n+  }\n+  /*!\n+   * lunr.Pipeline\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.Pipelines maintain an ordered list of functions to be applied to all\n+   * tokens in documents entering the search index and queries being ran against\n+   * the index.\n+   *\n+   * An instance of lunr.Index created with the lunr shortcut will contain a\n+   * pipeline with a stop word filter and an English language stemmer. Extra\n+   * functions can be added before or after either of these functions or these\n+   * default functions can be removed.\n+   *\n+   * When run the pipeline will call each function in turn, passing a token, the\n+   * index of that token in the original list of all tokens and finally a list of\n+   * all the original tokens.\n+   *\n+   * The output of functions in the pipeline will be passed to the next function\n+   * in the pipeline. To exclude a token from entering the index the function\n+   * should return undefined, the rest of the pipeline will not be called with\n+   * this token.\n+   *\n+   * For serialisation of pipelines to work, all functions used in an instance of\n+   * a pipeline should be registered with lunr.Pipeline. Registered functions can\n+   * then be loaded. If trying to load a serialised pipeline that uses functions\n+   * that are not registered an error will be thrown.\n+   *\n+   * If not planning on serialising the pipeline then registering pipeline functions\n+   * is not necessary.\n+   *\n+   * @constructor\n+   */\n+  lunr.Pipeline = function () {\n+    this._stack = []\n+  }\n+\n+  lunr.Pipeline.registeredFunctions = {}\n+\n+  /**\n+   * Register a function with the pipeline.\n+   *\n+   * Functions that are used in the pipeline should be registered if the pipeline\n+   * needs to be serialised, or a serialised pipeline needs to be loaded.\n+   *\n+   * Registering a function does not add it to a pipeline, functions must still be\n+   * added to instances of the pipeline for them to be used when running a pipeline.\n+   *\n+   * @param {Function} fn The function to check for.\n+   * @param {String} label The label to register this function with\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.registerFunction = function (fn, label) {\n+    if (label in this.registeredFunctions) {\n+      lunr.utils.warn('Overwriting existing registered function: ' + label)\n+    }\n+\n+    fn.label = label\n+    lunr.Pipeline.registeredFunctions[fn.label] = fn\n+  }\n+\n+  /**\n+   * Warns if the function is not registered as a Pipeline function.\n+   *\n+   * @param {Function} fn The function to check for.\n+   * @private\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n+    var isRegistered = fn.label && (fn.label in this.registeredFunctions)\n+\n+    if (!isRegistered) {\n+      lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn)\n+    }\n+  }\n+\n+  /**\n+   * Loads a previously serialised pipeline.\n+   *\n+   * All functions to be loaded must already be registered with lunr.Pipeline.\n+   * If any function from the serialised data has not been registered then an\n+   * error will be thrown.\n+   *\n+   * @param {Object} serialised The serialised pipeline to load.\n+   * @returns {lunr.Pipeline}\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.load = function (serialised) {\n+    var pipeline = new lunr.Pipeline\n+\n+    serialised.forEach(function (fnName) {\n+      var fn = lunr.Pipeline.registeredFunctions[fnName]\n+\n+      if (fn) {\n+        pipeline.add(fn)\n+      } else {\n+        throw new Error ('Cannot load un-registered function: ' + fnName)\n+      }\n+    })\n+\n+    return pipeline\n+  }\n+\n+  /**\n+   * Adds new functions to the end of the pipeline.\n+   *\n+   * Logs a warning if the function has not been registered.\n+   *\n+   * @param {Function} functions Any number of functions to add to the pipeline.\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.add = function () {\n+    var fns = Array.prototype.slice.call(arguments)\n+\n+    fns.forEach(function (fn) {\n+      lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n+      this._stack.push(fn)\n+    }, this)\n+  }\n+\n+  /**\n+   * Adds a single function after a function that already exists in the\n+   * pipeline.\n+   *\n+   * Logs a warning if the function has not been registered.\n+   *\n+   * @param {Function} existingFn A function that already exists in the pipeline.\n+   * @param {Function} newFn The new function to add to the pipeline.\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.after = function (existingFn, newFn) {\n+    lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n+\n+    var pos = this._stack.indexOf(existingFn) + 1\n+    this._stack.splice(pos, 0, newFn)\n+  }\n+\n+  /**\n+   * Adds a single function before a function that already exists in the\n+   * pipeline.\n+   *\n+   * Logs a warning if the function has not been registered.\n+   *\n+   * @param {Function} existingFn A function that already exists in the pipeline.\n+   * @param {Function} newFn The new function to add to the pipeline.\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.before = function (existingFn, newFn) {\n+    lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n+\n+    var pos = this._stack.indexOf(existingFn)\n+    this._stack.splice(pos, 0, newFn)\n+  }\n+\n+  /**\n+   * Removes a function from the pipeline.\n+   *\n+   * @param {Function} fn The function to remove from the pipeline.\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.remove = function (fn) {\n+    var pos = this._stack.indexOf(fn)\n+    this._stack.splice(pos, 1)\n+  }\n+\n+  /**\n+   * Runs the current list of functions that make up the pipeline against the\n+   * passed tokens.\n+   *\n+   * @param {Array} tokens The tokens to run through the pipeline.\n+   * @returns {Array}\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.run = function (tokens) {\n+    var out = [],\n+        tokenLength = tokens.length,\n+        stackLength = this._stack.length\n+\n+    for (var i = 0; i < tokenLength; i++) {\n+      var token = tokens[i]\n+\n+      for (var j = 0; j < stackLength; j++) {\n+        token = this._stack[j](token, i, tokens)\n+        if (token === void 0) break\n+      };\n+\n+      if (token !== void 0) out.push(token)\n+    };\n+\n+    return out\n+  }\n+\n+  /**\n+   * Resets the pipeline by removing any existing processors.\n+   *\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.reset = function () {\n+    this._stack = []\n+  }\n+\n+  /**\n+   * Returns a representation of the pipeline ready for serialisation.\n+   *\n+   * Logs a warning if the function has not been registered.\n+   *\n+   * @returns {Array}\n+   * @memberOf Pipeline\n+   */\n+  lunr.Pipeline.prototype.toJSON = function () {\n+    return this._stack.map(function (fn) {\n+      lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n+\n+      return fn.label\n+    })\n+  }\n+  /*!\n+   * lunr.Vector\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.Vectors implement vector related operations for\n+   * a series of elements.\n+   *\n+   * @constructor\n+   */\n+  lunr.Vector = function () {\n+    this._magnitude = null\n+    this.list = undefined\n+    this.length = 0\n+  }\n+\n+  /**\n+   * lunr.Vector.Node is a simple struct for each node\n+   * in a lunr.Vector.\n+   *\n+   * @private\n+   * @param {Number} The index of the node in the vector.\n+   * @param {Object} The data at this node in the vector.\n+   * @param {lunr.Vector.Node} The node directly after this node in the vector.\n+   * @constructor\n+   * @memberOf Vector\n+   */\n+  lunr.Vector.Node = function (idx, val, next) {\n+    this.idx = idx\n+    this.val = val\n+    this.next = next\n+  }\n+\n+  /**\n+   * Inserts a new value at a position in a vector.\n+   *\n+   * @param {Number} The index at which to insert a value.\n+   * @param {Object} The object to insert in the vector.\n+   * @memberOf Vector.\n+   */\n+  lunr.Vector.prototype.insert = function (idx, val) {\n+    var list = this.list\n+\n+    if (!list) {\n+      this.list = new lunr.Vector.Node (idx, val, list)\n+      return this.length++\n+    }\n+\n+    var prev = list,\n+        next = list.next\n+\n+    while (next != undefined) {\n+      if (idx < next.idx) {\n+        prev.next = new lunr.Vector.Node (idx, val, next)\n+        return this.length++\n+      }\n+\n+      prev = next, next = next.next\n+    }\n+\n+    prev.next = new lunr.Vector.Node (idx, val, next)\n+    return this.length++\n+  }\n+\n+  /**\n+   * Calculates the magnitude of this vector.\n+   *\n+   * @returns {Number}\n+   * @memberOf Vector\n+   */\n+  lunr.Vector.prototype.magnitude = function () {\n+    if (this._magniture) return this._magnitude\n+    var node = this.list,\n+        sumOfSquares = 0,\n+        val\n+\n+    while (node) {\n+      val = node.val\n+      sumOfSquares += val * val\n+      node = node.next\n+    }\n+\n+    return this._magnitude = Math.sqrt(sumOfSquares)\n+  }\n+\n+  /**\n+   * Calculates the dot product of this vector and another vector.\n+   *\n+   * @param {lunr.Vector} otherVector The vector to compute the dot product with.\n+   * @returns {Number}\n+   * @memberOf Vector\n+   */\n+  lunr.Vector.prototype.dot = function (otherVector) {\n+    var node = this.list,\n+        otherNode = otherVector.list,\n+        dotProduct = 0\n+\n+    while (node && otherNode) {\n+      if (node.idx < otherNode.idx) {\n+        node = node.next\n+      } else if (node.idx > otherNode.idx) {\n+        otherNode = otherNode.next\n+      } else {\n+        dotProduct += node.val * otherNode.val\n+        node = node.next\n+        otherNode = otherNode.next\n+      }\n+    }\n+\n+    return dotProduct\n+  }\n+\n+  /**\n+   * Calculates the cosine similarity between this vector and another\n+   * vector.\n+   *\n+   * @param {lunr.Vector} otherVector The other vector to calculate the\n+   * similarity with.\n+   * @returns {Number}\n+   * @memberOf Vector\n+   */\n+  lunr.Vector.prototype.similarity = function (otherVector) {\n+    return this.dot(otherVector) / (this.magnitude() * otherVector.magnitude())\n+  }\n+  /*!\n+   * lunr.SortedSet\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.SortedSets are used to maintain an array of uniq values in a sorted\n+   * order.\n+   *\n+   * @constructor\n+   */\n+  lunr.SortedSet = function () {\n+    this.length = 0\n+    this.elements = []\n+  }\n+\n+  /**\n+   * Loads a previously serialised sorted set.\n+   *\n+   * @param {Array} serialisedData The serialised set to load.\n+   * @returns {lunr.SortedSet}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.load = function (serialisedData) {\n+    var set = new this\n+\n+    set.elements = serialisedData\n+    set.length = serialisedData.length\n+\n+    return set\n+  }\n+\n+  /**\n+   * Inserts new items into the set in the correct position to maintain the\n+   * order.\n+   *\n+   * @param {Object} The objects to add to this set.\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.add = function () {\n+    Array.prototype.slice.call(arguments).forEach(function (element) {\n+      if (~this.indexOf(element)) return\n+      this.elements.splice(this.locationFor(element), 0, element)\n+    }, this)\n+\n+    this.length = this.elements.length\n+  }\n+\n+  /**\n+   * Converts this sorted set into an array.\n+   *\n+   * @returns {Array}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.toArray = function () {\n+    return this.elements.slice()\n+  }\n+\n+  /**\n+   * Creates a new array with the results of calling a provided function on every\n+   * element in this sorted set.\n+   *\n+   * Delegates to Array.prototype.map and has the same signature.\n+   *\n+   * @param {Function} fn The function that is called on each element of the\n+   * set.\n+   * @param {Object} ctx An optional object that can be used as the context\n+   * for the function fn.\n+   * @returns {Array}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.map = function (fn, ctx) {\n+    return this.elements.map(fn, ctx)\n+  }\n+\n+  /**\n+   * Executes a provided function once per sorted set element.\n+   *\n+   * Delegates to Array.prototype.forEach and has the same signature.\n+   *\n+   * @param {Function} fn The function that is called on each element of the\n+   * set.\n+   * @param {Object} ctx An optional object that can be used as the context\n+   * @memberOf SortedSet\n+   * for the function fn.\n+   */\n+  lunr.SortedSet.prototype.forEach = function (fn, ctx) {\n+    return this.elements.forEach(fn, ctx)\n+  }\n+\n+  /**\n+   * Returns the index at which a given element can be found in the\n+   * sorted set, or -1 if it is not present.\n+   *\n+   * @param {Object} elem The object to locate in the sorted set.\n+   * @param {Number} start An optional index at which to start searching from\n+   * within the set.\n+   * @param {Number} end An optional index at which to stop search from within\n+   * the set.\n+   * @returns {Number}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.indexOf = function (elem, start, end) {\n+    var start = start || 0,\n+        end = end || this.elements.length,\n+        sectionLength = end - start,\n+        pivot = start + Math.floor(sectionLength / 2),\n+        pivotElem = this.elements[pivot]\n+\n+    if (sectionLength <= 1) {\n+      if (pivotElem === elem) {\n+        return pivot\n+      } else {\n+        return -1\n+      }\n+    }\n+\n+    if (pivotElem < elem) return this.indexOf(elem, pivot, end)\n+    if (pivotElem > elem) return this.indexOf(elem, start, pivot)\n+    if (pivotElem === elem) return pivot\n+  }\n+\n+  /**\n+   * Returns the position within the sorted set that an element should be\n+   * inserted at to maintain the current order of the set.\n+   *\n+   * This function assumes that the element to search for does not already exist\n+   * in the sorted set.\n+   *\n+   * @param {Object} elem The elem to find the position for in the set\n+   * @param {Number} start An optional index at which to start searching from\n+   * within the set.\n+   * @param {Number} end An optional index at which to stop search from within\n+   * the set.\n+   * @returns {Number}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.locationFor = function (elem, start, end) {\n+    var start = start || 0,\n+        end = end || this.elements.length,\n+        sectionLength = end - start,\n+        pivot = start + Math.floor(sectionLength / 2),\n+        pivotElem = this.elements[pivot]\n+\n+    if (sectionLength <= 1) {\n+      if (pivotElem > elem) return pivot\n+      if (pivotElem < elem) return pivot + 1\n+    }\n+\n+    if (pivotElem < elem) return this.locationFor(elem, pivot, end)\n+    if (pivotElem > elem) return this.locationFor(elem, start, pivot)\n+  }\n+\n+  /**\n+   * Creates a new lunr.SortedSet that contains the elements in the intersection\n+   * of this set and the passed set.\n+   *\n+   * @param {lunr.SortedSet} otherSet The set to intersect with this set.\n+   * @returns {lunr.SortedSet}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.intersect = function (otherSet) {\n+    var intersectSet = new lunr.SortedSet,\n+        i = 0, j = 0,\n+        a_len = this.length, b_len = otherSet.length,\n+        a = this.elements, b = otherSet.elements\n+\n+    while (true) {\n+      if (i > a_len - 1 || j > b_len - 1) break\n+\n+      if (a[i] === b[j]) {\n+        intersectSet.add(a[i])\n+        i++, j++\n+        continue\n+      }\n+\n+      if (a[i] < b[j]) {\n+        i++\n+        continue\n+      }\n+\n+      if (a[i] > b[j]) {\n+        j++\n+        continue\n+      }\n+    };\n+\n+    return intersectSet\n+  }\n+\n+  /**\n+   * Makes a copy of this set\n+   *\n+   * @returns {lunr.SortedSet}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.clone = function () {\n+    var clone = new lunr.SortedSet\n+\n+    clone.elements = this.toArray()\n+    clone.length = clone.elements.length\n+\n+    return clone\n+  }\n+\n+  /**\n+   * Creates a new lunr.SortedSet that contains the elements in the union\n+   * of this set and the passed set.\n+   *\n+   * @param {lunr.SortedSet} otherSet The set to union with this set.\n+   * @returns {lunr.SortedSet}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.union = function (otherSet) {\n+    var longSet, shortSet, unionSet\n+\n+    if (this.length >= otherSet.length) {\n+      longSet = this, shortSet = otherSet\n+    } else {\n+      longSet = otherSet, shortSet = this\n+    }\n+\n+    unionSet = longSet.clone()\n+\n+    unionSet.add.apply(unionSet, shortSet.toArray())\n+\n+    return unionSet\n+  }\n+\n+  /**\n+   * Returns a representation of the sorted set ready for serialisation.\n+   *\n+   * @returns {Array}\n+   * @memberOf SortedSet\n+   */\n+  lunr.SortedSet.prototype.toJSON = function () {\n+    return this.toArray()\n+  }\n+  /*!\n+   * lunr.Index\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.Index is object that manages a search index.  It contains the indexes\n+   * and stores all the tokens and document lookups.  It also provides the main\n+   * user facing API for the library.\n+   *\n+   * @constructor\n+   */\n+  lunr.Index = function () {\n+    this._fields = []\n+    this._ref = 'id'\n+    this.pipeline = new lunr.Pipeline\n+    this.documentStore = new lunr.Store\n+    this.tokenStore = new lunr.TokenStore\n+    this.corpusTokens = new lunr.SortedSet\n+    this.eventEmitter =  new lunr.EventEmitter\n+\n+    this._idfCache = {}\n+\n+    this.on('add', 'remove', 'update', (function () {\n+      this._idfCache = {}\n+    }).bind(this))\n+  }\n+\n+  /**\n+   * Bind a handler to events being emitted by the index.\n+   *\n+   * The handler can be bound to many events at the same time.\n+   *\n+   * @param {String} [eventName] The name(s) of events to bind the function to.\n+   * @param {Function} handler The serialised set to load.\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.on = function () {\n+    var args = Array.prototype.slice.call(arguments)\n+    return this.eventEmitter.addListener.apply(this.eventEmitter, args)\n+  }\n+\n+  /**\n+   * Removes a handler from an event being emitted by the index.\n+   *\n+   * @param {String} eventName The name of events to remove the function from.\n+   * @param {Function} handler The serialised set to load.\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.off = function (name, fn) {\n+    return this.eventEmitter.removeListener(name, fn)\n+  }\n+\n+  /**\n+   * Loads a previously serialised index.\n+   *\n+   * Issues a warning if the index being imported was serialised\n+   * by a different version of lunr.\n+   *\n+   * @param {Object} serialisedData The serialised set to load.\n+   * @returns {lunr.Index}\n+   * @memberOf Index\n+   */\n+  lunr.Index.load = function (serialisedData) {\n+    if (serialisedData.version !== lunr.version) {\n+      lunr.utils.warn('version mismatch: current ' + lunr.version + ' importing ' + serialisedData.version)\n+    }\n+\n+    var idx = new this\n+\n+    idx._fields = serialisedData.fields\n+    idx._ref = serialisedData.ref\n+\n+    idx.documentStore = lunr.Store.load(serialisedData.documentStore)\n+    idx.tokenStore = lunr.TokenStore.load(serialisedData.tokenStore)\n+    idx.corpusTokens = lunr.SortedSet.load(serialisedData.corpusTokens)\n+    idx.pipeline = lunr.Pipeline.load(serialisedData.pipeline)\n+\n+    return idx\n+  }\n+\n+  /**\n+   * Adds a field to the list of fields that will be searchable within documents\n+   * in the index.\n+   *\n+   * An optional boost param can be passed to affect how much tokens in this field\n+   * rank in search results, by default the boost value is 1.\n+   *\n+   * Fields should be added before any documents are added to the index, fields\n+   * that are added after documents are added to the index will only apply to new\n+   * documents added to the index.\n+   *\n+   * @param {String} fieldName The name of the field within the document that\n+   * should be indexed\n+   * @param {Number} boost An optional boost that can be applied to terms in this\n+   * field.\n+   * @returns {lunr.Index}\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.field = function (fieldName, opts) {\n+    var opts = opts || {},\n+        field = { name: fieldName, boost: opts.boost || 1 }\n+\n+    this._fields.push(field)\n+    return this\n+  }\n+\n+  /**\n+   * Sets the property used to uniquely identify documents added to the index,\n+   * by default this property is 'id'.\n+   *\n+   * This should only be changed before adding documents to the index, changing\n+   * the ref property without resetting the index can lead to unexpected results.\n+   *\n+   * @param {String} refName The property to use to uniquely identify the\n+   * documents in the index.\n+   * @param {Boolean} emitEvent Whether to emit add events, defaults to true\n+   * @returns {lunr.Index}\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.ref = function (refName) {\n+    this._ref = refName\n+    return this\n+  }\n+\n+  /**\n+   * Add a document to the index.\n+   *\n+   * This is the way new documents enter the index, this function will run the\n+   * fields from the document through the index's pipeline and then add it to\n+   * the index, it will then show up in search results.\n+   *\n+   * An 'add' event is emitted with the document that has been added and the index\n+   * the document has been added to. This event can be silenced by passing false\n+   * as the second argument to add.\n+   *\n+   * @param {Object} doc The document to add to the index.\n+   * @param {Boolean} emitEvent Whether or not to emit events, default true.\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.add = function (doc, emitEvent) {\n+    var docTokens = {},\n+        allDocumentTokens = new lunr.SortedSet,\n+        docRef = doc[this._ref],\n+        emitEvent = emitEvent === undefined ? true : emitEvent\n+\n+    this._fields.forEach(function (field) {\n+      var fieldTokens = this.pipeline.run(lunr.tokenizer(doc[field.name]))\n+\n+      docTokens[field.name] = fieldTokens\n+      lunr.SortedSet.prototype.add.apply(allDocumentTokens, fieldTokens)\n+    }, this)\n+\n+    this.documentStore.set(docRef, allDocumentTokens)\n+    lunr.SortedSet.prototype.add.apply(this.corpusTokens, allDocumentTokens.toArray())\n+\n+    for (var i = 0; i < allDocumentTokens.length; i++) {\n+      var token = allDocumentTokens.elements[i]\n+      var tf = this._fields.reduce(function (memo, field) {\n+        var fieldLength = docTokens[field.name].length\n+\n+        if (!fieldLength) return memo\n+\n+        var tokenCount = docTokens[field.name].filter(function (t) { return t === token }).length\n+\n+        return memo + (tokenCount / fieldLength * field.boost)\n+      }, 0)\n+\n+      this.tokenStore.add(token, { ref: docRef, tf: tf })\n+    };\n+\n+    if (emitEvent) this.eventEmitter.emit('add', doc, this)\n+  }\n+\n+  /**\n+   * Removes a document from the index.\n+   *\n+   * To make sure documents no longer show up in search results they can be\n+   * removed from the index using this method.\n+   *\n+   * The document passed only needs to have the same ref property value as the\n+   * document that was added to the index, they could be completely different\n+   * objects.\n+   *\n+   * A 'remove' event is emitted with the document that has been removed and the index\n+   * the document has been removed from. This event can be silenced by passing false\n+   * as the second argument to remove.\n+   *\n+   * @param {Object} doc The document to remove from the index.\n+   * @param {Boolean} emitEvent Whether to emit remove events, defaults to true\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.remove = function (doc, emitEvent) {\n+    var docRef = doc[this._ref],\n+        emitEvent = emitEvent === undefined ? true : emitEvent\n+\n+    if (!this.documentStore.has(docRef)) return\n+\n+    var docTokens = this.documentStore.get(docRef)\n+\n+    this.documentStore.remove(docRef)\n+\n+    docTokens.forEach(function (token) {\n+      this.tokenStore.remove(token, docRef)\n+    }, this)\n+\n+    if (emitEvent) this.eventEmitter.emit('remove', doc, this)\n+  }\n+\n+  /**\n+   * Updates a document in the index.\n+   *\n+   * When a document contained within the index gets updated, fields changed,\n+   * added or removed, to make sure it correctly matched against search queries,\n+   * it should be updated in the index.\n+   *\n+   * This method is just a wrapper around `remove` and `add`\n+   *\n+   * An 'update' event is emitted with the document that has been updated and the index.\n+   * This event can be silenced by passing false as the second argument to update. Only\n+   * an update event will be fired, the 'add' and 'remove' events of the underlying calls\n+   * are silenced.\n+   *\n+   * @param {Object} doc The document to update in the index.\n+   * @param {Boolean} emitEvent Whether to emit update events, defaults to true\n+   * @see Index.prototype.remove\n+   * @see Index.prototype.add\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.update = function (doc, emitEvent) {\n+    var emitEvent = emitEvent === undefined ? true : emitEvent\n+\n+    this.remove(doc, false)\n+    this.add(doc, false)\n+\n+    if (emitEvent) this.eventEmitter.emit('update', doc, this)\n+  }\n+\n+  /**\n+   * Calculates the inverse document frequency for a token within the index.\n+   *\n+   * @param {String} token The token to calculate the idf of.\n+   * @see Index.prototype.idf\n+   * @private\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.idf = function (term) {\n+    var cacheKey = \"@\" + term\n+    if (Object.prototype.hasOwnProperty.call(this._idfCache, cacheKey)) return this._idfCache[cacheKey]\n+\n+    var documentFrequency = this.tokenStore.count(term),\n+        idf = 1\n+\n+    if (documentFrequency > 0) {\n+      idf = 1 + Math.log(this.tokenStore.length / documentFrequency)\n+    }\n+\n+    return this._idfCache[cacheKey] = idf\n+  }\n+\n+  /**\n+   * Searches the index using the passed query.\n+   *\n+   * Queries should be a string, multiple words are allowed and will lead to an\n+   * AND based query, e.g. `idx.search('foo bar')` will run a search for\n+   * documents containing both 'foo' and 'bar'.\n+   *\n+   * All query tokens are passed through the same pipeline that document tokens\n+   * are passed through, so any language processing involved will be run on every\n+   * query term.\n+   *\n+   * Each query term is expanded, so that the term 'he' might be expanded to\n+   * 'hello' and 'help' if those terms were already included in the index.\n+   *\n+   * Matching documents are returned as an array of objects, each object contains\n+   * the matching document ref, as set for this index, and the similarity score\n+   * for this document against the query.\n+   *\n+   * @param {String} query The query to search the index with.\n+   * @returns {Object}\n+   * @see Index.prototype.idf\n+   * @see Index.prototype.documentVector\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.search = function (query) {\n+    var queryTokens = this.pipeline.run(lunr.tokenizer(query)),\n+        queryVector = new lunr.Vector,\n+        documentSets = [],\n+        fieldBoosts = this._fields.reduce(function (memo, f) { return memo + f.boost }, 0)\n+\n+    var hasSomeToken = queryTokens.some(function (token) {\n+      return this.tokenStore.has(token)\n+    }, this)\n+\n+    if (!hasSomeToken) return []\n+\n+    queryTokens\n+        .forEach(function (token, i, tokens) {\n+          var tf = 1 / tokens.length * this._fields.length * fieldBoosts,\n+              self = this\n+\n+          var set = this.tokenStore.expand(token).reduce(function (memo, key) {\n+            var pos = self.corpusTokens.indexOf(key),\n+                idf = self.idf(key),\n+                similarityBoost = 1,\n+                set = new lunr.SortedSet\n+\n+            // if the expanded key is not an exact match to the token then\n+            // penalise the score for this key by how different the key is\n+            // to the token.\n+            if (key !== token) {\n+              var diff = Math.max(3, key.length - token.length)\n+              similarityBoost = 1 / Math.log(diff)\n+            }\n+\n+            // calculate the query tf-idf score for this token\n+            // applying an similarityBoost to ensure exact matches\n+            // these rank higher than expanded terms\n+            if (pos > -1) queryVector.insert(pos, tf * idf * similarityBoost)\n+\n+            // add all the documents that have this key into a set\n+            Object.keys(self.tokenStore.get(key)).forEach(function (ref) { set.add(ref) })\n+\n+            return memo.union(set)\n+          }, new lunr.SortedSet)\n+\n+          documentSets.push(set)\n+        }, this)\n+\n+    var documentSet = documentSets.reduce(function (memo, set) {\n+      return memo.intersect(set)\n+    })\n+\n+    return documentSet\n+        .map(function (ref) {\n+          return { ref: ref, score: queryVector.similarity(this.documentVector(ref)) }\n+        }, this)\n+        .sort(function (a, b) {\n+          return b.score - a.score\n+        })\n+  }\n+\n+  /**\n+   * Generates a vector containing all the tokens in the document matching the\n+   * passed documentRef.\n+   *\n+   * The vector contains the tf-idf score for each token contained in the\n+   * document with the passed documentRef.  The vector will contain an element\n+   * for every token in the indexes corpus, if the document does not contain that\n+   * token the element will be 0.\n+   *\n+   * @param {Object} documentRef The ref to find the document with.\n+   * @returns {lunr.Vector}\n+   * @private\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.documentVector = function (documentRef) {\n+    var documentTokens = this.documentStore.get(documentRef),\n+        documentTokensLength = documentTokens.length,\n+        documentVector = new lunr.Vector\n+\n+    for (var i = 0; i < documentTokensLength; i++) {\n+      var token = documentTokens.elements[i],\n+          tf = this.tokenStore.get(token)[documentRef].tf,\n+          idf = this.idf(token)\n+\n+      documentVector.insert(this.corpusTokens.indexOf(token), tf * idf)\n+    };\n+\n+    return documentVector\n+  }\n+\n+  /**\n+   * Returns a representation of the index ready for serialisation.\n+   *\n+   * @returns {Object}\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.toJSON = function () {\n+    return {\n+      version: lunr.version,\n+      fields: this._fields,\n+      ref: this._ref,\n+      documentStore: this.documentStore.toJSON(),\n+      tokenStore: this.tokenStore.toJSON(),\n+      corpusTokens: this.corpusTokens.toJSON(),\n+      pipeline: this.pipeline.toJSON()\n+    }\n+  }\n+\n+  /**\n+   * Applies a plugin to the current index.\n+   *\n+   * A plugin is a function that is called with the index as its context.\n+   * Plugins can be used to customise or extend the behaviour the index\n+   * in some way. A plugin is just a function, that encapsulated the custom\n+   * behaviour that should be applied to the index.\n+   *\n+   * The plugin function will be called with the index as its argument, additional\n+   * arguments can also be passed when calling use. The function will be called\n+   * with the index as its context.\n+   *\n+   * Example:\n+   *\n+   *     var myPlugin = function (idx, arg1, arg2) {\n+ *       // `this` is the index to be extended\n+ *       // apply any extensions etc here.\n+ *     }\n+   *\n+   *     var idx = lunr(function () {\n+ *       this.use(myPlugin, 'arg1', 'arg2')\n+ *     })\n+   *\n+   * @param {Function} plugin The plugin to apply.\n+   * @memberOf Index\n+   */\n+  lunr.Index.prototype.use = function (plugin) {\n+    var args = Array.prototype.slice.call(arguments, 1)\n+    args.unshift(this)\n+    plugin.apply(this, args)\n+  }\n+  /*!\n+   * lunr.Store\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.Store is a simple key-value store used for storing sets of tokens for\n+   * documents stored in index.\n+   *\n+   * @constructor\n+   * @module\n+   */\n+  lunr.Store = function () {\n+    this.store = {}\n+    this.length = 0\n+  }\n+\n+  /**\n+   * Loads a previously serialised store\n+   *\n+   * @param {Object} serialisedData The serialised store to load.\n+   * @returns {lunr.Store}\n+   * @memberOf Store\n+   */\n+  lunr.Store.load = function (serialisedData) {\n+    var store = new this\n+\n+    store.length = serialisedData.length\n+    store.store = Object.keys(serialisedData.store).reduce(function (memo, key) {\n+      memo[key] = lunr.SortedSet.load(serialisedData.store[key])\n+      return memo\n+    }, {})\n+\n+    return store\n+  }\n+\n+  /**\n+   * Stores the given tokens in the store against the given id.\n+   *\n+   * @param {Object} id The key used to store the tokens against.\n+   * @param {Object} tokens The tokens to store against the key.\n+   * @memberOf Store\n+   */\n+  lunr.Store.prototype.set = function (id, tokens) {\n+    if (!this.has(id)) this.length++\n+    this.store[id] = tokens\n+  }\n+\n+  /**\n+   * Retrieves the tokens from the store for a given key.\n+   *\n+   * @param {Object} id The key to lookup and retrieve from the store.\n+   * @returns {Object}\n+   * @memberOf Store\n+   */\n+  lunr.Store.prototype.get = function (id) {\n+    return this.store[id]\n+  }\n+\n+  /**\n+   * Checks whether the store contains a key.\n+   *\n+   * @param {Object} id The id to look up in the store.\n+   * @returns {Boolean}\n+   * @memberOf Store\n+   */\n+  lunr.Store.prototype.has = function (id) {\n+    return id in this.store\n+  }\n+\n+  /**\n+   * Removes the value for a key in the store.\n+   *\n+   * @param {Object} id The id to remove from the store.\n+   * @memberOf Store\n+   */\n+  lunr.Store.prototype.remove = function (id) {\n+    if (!this.has(id)) return\n+\n+    delete this.store[id]\n+    this.length--\n+  }\n+\n+  /**\n+   * Returns a representation of the store ready for serialisation.\n+   *\n+   * @returns {Object}\n+   * @memberOf Store\n+   */\n+  lunr.Store.prototype.toJSON = function () {\n+    return {\n+      store: this.store,\n+      length: this.length\n+    }\n+  }\n+\n+  /*!\n+   * lunr.stemmer\n+   * Copyright (C) 2014 Oliver Nightingale\n+   * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n+   */\n+\n+  /**\n+   * lunr.stemmer is an english language stemmer, this is a JavaScript\n+   * implementation of the PorterStemmer taken from http://tartaurs.org/~martin\n+   *\n+   * @module\n+   * @param {String} str The string to stem\n+   * @returns {String}\n+   * @see lunr.Pipeline\n+   */\n+  lunr.stemmer = (function(){\n+    var step2list = {\n+          \"ational\" : \"ate\",\n+          \"tional\" : \"tion\",\n+          \"enci\" : \"ence\",\n+          \"anci\" : \"ance\",\n+          \"izer\" : \"ize\",\n+          \"bli\" : \"ble\",\n+          \"alli\" : \"al\",\n+          \"entli\" : \"ent\",\n+          \"eli\" : \"e\",\n+          \"ousli\" : \"ous\",\n+          \"ization\" : \"ize\",\n+          \"ation\" : \"ate\",\n+          \"ator\" : \"ate\",\n+          \"alism\" : \"al\",\n+          \"iveness\" : \"ive\",\n+          \"fulness\" : \"ful\",\n+          \"ousness\" : \"ous\",\n+          \"aliti\" : \"al\",\n+          \"iviti\" : \"ive\",\n+          \"biliti\" : \"ble\",\n+          \"logi\" : \"log\"\n+        },\n+\n+        step3list = {\n+          \"icate\" : \"ic\",\n+          \"ative\" : \"\",\n+          \"alize\" : \"al\",\n+          \"iciti\" : \"ic\",\n+          \"ical\" : \"ic\",\n+          \"ful\" : \"\",\n+          \"ness\" : \"\"\n+        },\n+\n+        c = \"[^aeiou]\",          // consonant\n+        v = \"[aeiouy]\",          // vowel\n+        C = c + \"[^aeiouy]*\",    // consonant sequence\n+        V = v + \"[aeiou]*\",      // vowel sequence\n+\n+        mgr0 = \"^(\" + C + \")?\" + V + C,               // [C]VC... is m>0\n+        meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\",  // [C]VC[V] is m=1\n+        mgr1 = \"^(\" + C + \")?\" + V + C + V + C,       // [C]VCVC... is m>1\n+        s_v = \"^(\" + C + \")?\" + v;                   // vowel in stem\n+\n+    var re_mgr0 = new RegExp(mgr0);\n+    var re_mgr1 = new RegExp(mgr1);\n+    var re_meq1 = new RegExp(meq1);\n+    var re_s_v = new RegExp(s_v);\n+\n+    var re_1a = /^(.+?)(ss|i)es$/;\n+    var re2_1a = /^(.+?)([^s])s$/;\n+    var re_1b = /^(.+?)eed$/;\n+    var re2_1b = /^(.+?)(ed|ing)$/;\n+    var re_1b_2 = /.$/;\n+    var re2_1b_2 = /(at|bl|iz)$/;\n+    var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n+    var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n+\n+    var re_1c = /^(.+?[^aeiou])y$/;\n+    var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n+\n+    var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n+\n+    var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n+    var re2_4 = /^(.+?)(s|t)(ion)$/;\n+\n+    var re_5 = /^(.+?)e$/;\n+    var re_5_1 = /ll$/;\n+    var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n+\n+    var porterStemmer = function porterStemmer(w) {\n+      var   stem,\n+          suffix,\n+          firstch,\n+          re,\n+          re2,\n+          re3,\n+          re4;\n+\n+      if (w.length < 3) { return w; }\n+\n+      firstch = w.substr(0,1);\n+      if (firstch == \"y\") {\n+        w = firstch.toUpperCase() + w.substr(1);\n+      }\n+\n+      // Step 1a\n+      re = re_1a\n+      re2 = re2_1a;\n+\n+      if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n+      else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n+\n+      // Step 1b\n+      re = re_1b;\n+      re2 = re2_1b;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        re = re_mgr0;\n+        if (re.test(fp[1])) {\n+          re = re_1b_2;\n+          w = w.replace(re,\"\");\n+        }\n+      } else if (re2.test(w)) {\n+        var fp = re2.exec(w);\n+        stem = fp[1];\n+        re2 = re_s_v;\n+        if (re2.test(stem)) {\n+          w = stem;\n+          re2 = re2_1b_2;\n+          re3 = re3_1b_2;\n+          re4 = re4_1b_2;\n+          if (re2.test(w)) {  w = w + \"e\"; }\n+          else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n+          else if (re4.test(w)) { w = w + \"e\"; }\n+        }\n+      }\n+\n+      // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n+      re = re_1c;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        stem = fp[1];\n+        w = stem + \"i\";\n+      }\n+\n+      // Step 2\n+      re = re_2;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        stem = fp[1];\n+        suffix = fp[2];\n+        re = re_mgr0;\n+        if (re.test(stem)) {\n+          w = stem + step2list[suffix];\n+        }\n+      }\n+\n+      // Step 3\n+      re = re_3;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        stem = fp[1];\n+        suffix = fp[2];\n+        re = re_mgr0;\n+        if (re.test(stem)) {\n+          w = stem + step3list[suffix];\n+        }\n+      }\n+\n+      // Step 4\n+      re = re_4;\n+      re2 = re2_4;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        stem = fp[1];\n+        re = re_mgr1;\n+        if (re.test(stem)) {\n+          w = stem;\n+        }\n+      } else if (re2.test(w)) {\n+        var fp = re2.exec(w);\n+        stem = fp[1] + fp[2];\n+        re2 = re_mgr1;\n+        if (re2.test(stem)) {\n+          w = stem;\n+        }\n+      }\n+\n+      // Step 5\n+      re = re_5;\n+      if (re.test(w)) {\n+        var fp = re.exec(w);\n+        stem = fp[1];\n+        re = re_mgr1;\n+        re2 = re_meq1;\n+        re3 = re3_5;\n+        if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n+          w = stem;\n+        }\n+      }\n+\n+      re = re_5_1;\n+      re2 = re_mgr1;\n+      if (re.test(w) && re2.test(w)) {\n+        re = re_1b_2;\n+        w = w.replace(re,\"\");\n+      }\n+\n+      // and turn initial Y back to y\n+\n+      if (firstch == \"y\") {\n+        w = firstch.toLowerCase() + w.substr(1);\n+      }\n+\n+      return w;\n+    };\n+\n+    return porterStemmer;\n+  })();\n+\n+  lunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')\n+  /*!\n+   * lunr.stopWordFilter\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.stopWordFilter is an English language stop word list filter, any words\n+   * contained in the list will not be passed through the filter.\n+   *\n+   * This is intended to be used in the Pipeline. If the token does not pass the\n+   * filter then undefined will be returned.\n+   *\n+   * @module\n+   * @param {String} token The token to pass through the filter\n+   * @returns {String}\n+   * @see lunr.Pipeline\n+   */\n+  lunr.stopWordFilter = function (token) {\n+    if (lunr.stopWordFilter.stopWords.indexOf(token) === -1) return token\n+  }\n+\n+  lunr.stopWordFilter.stopWords = new lunr.SortedSet\n+  lunr.stopWordFilter.stopWords.length = 119\n+  lunr.stopWordFilter.stopWords.elements = [\n+    \"\",\n+    \"a\",\n+    \"able\",\n+    \"about\",\n+    \"across\",\n+    \"after\",\n+    \"all\",\n+    \"almost\",\n+    \"also\",\n+    \"am\",\n+    \"among\",\n+    \"an\",\n+    \"and\",\n+    \"any\",\n+    \"are\",\n+    \"as\",\n+    \"at\",\n+    \"be\",\n+    \"because\",\n+    \"been\",\n+    \"but\",\n+    \"by\",\n+    \"can\",\n+    \"cannot\",\n+    \"could\",\n+    \"dear\",\n+    \"did\",\n+    \"do\",\n+    \"does\",\n+    \"either\",\n+    \"else\",\n+    \"ever\",\n+    \"every\",\n+    \"for\",\n+    \"from\",\n+    \"get\",\n+    \"got\",\n+    \"had\",\n+    \"has\",\n+    \"have\",\n+    \"he\",\n+    \"her\",\n+    \"hers\",\n+    \"him\",\n+    \"his\",\n+    \"how\",\n+    \"however\",\n+    \"i\",\n+    \"if\",\n+    \"in\",\n+    \"into\",\n+    \"is\",\n+    \"it\",\n+    \"its\",\n+    \"just\",\n+    \"least\",\n+    \"let\",\n+    \"like\",\n+    \"likely\",\n+    \"may\",\n+    \"me\",\n+    \"might\",\n+    \"most\",\n+    \"must\",\n+    \"my\",\n+    \"neither\",\n+    \"no\",\n+    \"nor\",\n+    \"not\",\n+    \"of\",\n+    \"off\",\n+    \"often\",\n+    \"on\",\n+    \"only\",\n+    \"or\",\n+    \"other\",\n+    \"our\",\n+    \"own\",\n+    \"rather\",\n+    \"said\",\n+    \"say\",\n+    \"says\",\n+    \"she\",\n+    \"should\",\n+    \"since\",\n+    \"so\",\n+    \"some\",\n+    \"than\",\n+    \"that\",\n+    \"the\",\n+    \"their\",\n+    \"them\",\n+    \"then\",\n+    \"there\",\n+    \"these\",\n+    \"they\",\n+    \"this\",\n+    \"tis\",\n+    \"to\",\n+    \"too\",\n+    \"twas\",\n+    \"us\",\n+    \"wants\",\n+    \"was\",\n+    \"we\",\n+    \"were\",\n+    \"what\",\n+    \"when\",\n+    \"where\",\n+    \"which\",\n+    \"while\",\n+    \"who\",\n+    \"whom\",\n+    \"why\",\n+    \"will\",\n+    \"with\",\n+    \"would\",\n+    \"yet\",\n+    \"you\",\n+    \"your\"\n+  ]\n+\n+  lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')\n+  /*!\n+   * lunr.trimmer\n+   * Copyright (C) 2014 Oliver Nightingale\n+   */\n+\n+  /**\n+   * lunr.trimmer is a pipeline function for trimming non word\n+   * characters from the begining and end of tokens before they\n+   * enter the index.\n+   *\n+   * This implementation may not work correctly for non latin\n+   * characters and should either be removed or adapted for use\n+   * with languages with non-latin characters.\n+   *\n+   * @module\n+   * @param {String} token The token to pass through the filter\n+   * @returns {String}\n+   * @see lunr.Pipeline\n+   */\n+  lunr.trimmer = function (token) {\n+    return token\n+        .replace(/^\\W+/, '')\n+        .replace(/\\W+$/, '')\n+  }\n+\n+  lunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')\n+  /*!\n+   * lunr.stemmer\n+   * Copyright (C) 2014 Oliver Nightingale\n+   * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n+   */\n+\n+  /**\n+   * lunr.TokenStore is used for efficient storing and lookup of the reverse\n+   * index of token to document ref.\n+   *\n+   * @constructor\n+   */\n+  lunr.TokenStore = function () {\n+    this.root = { docs: {} }\n+    this.length = 0\n+  }\n+\n+  /**\n+   * Loads a previously serialised token store\n+   *\n+   * @param {Object} serialisedData The serialised token store to load.\n+   * @returns {lunr.TokenStore}\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.load = function (serialisedData) {\n+    var store = new this\n+\n+    store.root = serialisedData.root\n+    store.length = serialisedData.length\n+\n+    return store\n+  }\n+\n+  /**\n+   * Adds a new token doc pair to the store.\n+   *\n+   * By default this function starts at the root of the current store, however\n+   * it can start at any node of any token store if required.\n+   *\n+   * @param {String} token The token to store the doc under\n+   * @param {Object} doc The doc to store against the token\n+   * @param {Object} root An optional node at which to start looking for the\n+   * correct place to enter the doc, by default the root of this lunr.TokenStore\n+   * is used.\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.add = function (token, doc, root) {\n+    var root = root || this.root,\n+        key = token[0],\n+        rest = token.slice(1)\n+\n+    if (!(key in root)) root[key] = {docs: {}}\n+\n+    if (rest.length === 0) {\n+      root[key].docs[doc.ref] = doc\n+      this.length += 1\n+      return\n+    } else {\n+      return this.add(rest, doc, root[key])\n+    }\n+  }\n+\n+  /**\n+   * Checks whether this key is contained within this lunr.TokenStore.\n+   *\n+   * By default this function starts at the root of the current store, however\n+   * it can start at any node of any token store if required.\n+   *\n+   * @param {String} token The token to check for\n+   * @param {Object} root An optional node at which to start\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.has = function (token) {\n+    if (!token) return false\n+\n+    var node = this.root\n+\n+    for (var i = 0; i < token.length; i++) {\n+      if (!node[token[i]]) return false\n+\n+      node = node[token[i]]\n+    }\n+\n+    return true\n+  }\n+\n+  /**\n+   * Retrieve a node from the token store for a given token.\n+   *\n+   * By default this function starts at the root of the current store, however\n+   * it can start at any node of any token store if required.\n+   *\n+   * @param {String} token The token to get the node for.\n+   * @param {Object} root An optional node at which to start.\n+   * @returns {Object}\n+   * @see TokenStore.prototype.get\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.getNode = function (token) {\n+    if (!token) return {}\n+\n+    var node = this.root\n+\n+    for (var i = 0; i < token.length; i++) {\n+      if (!node[token[i]]) return {}\n+\n+      node = node[token[i]]\n+    }\n+\n+    return node\n+  }\n+\n+  /**\n+   * Retrieve the documents for a node for the given token.\n+   *\n+   * By default this function starts at the root of the current store, however\n+   * it can start at any node of any token store if required.\n+   *\n+   * @param {String} token The token to get the documents for.\n+   * @param {Object} root An optional node at which to start.\n+   * @returns {Object}\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.get = function (token, root) {\n+    return this.getNode(token, root).docs || {}\n+  }\n+\n+  lunr.TokenStore.prototype.count = function (token, root) {\n+    return Object.keys(this.get(token, root)).length\n+  }\n+\n+  /**\n+   * Remove the document identified by ref from the token in the store.\n+   *\n+   * By default this function starts at the root of the current store, however\n+   * it can start at any node of any token store if required.\n+   *\n+   * @param {String} token The token to get the documents for.\n+   * @param {String} ref The ref of the document to remove from this token.\n+   * @param {Object} root An optional node at which to start.\n+   * @returns {Object}\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.remove = function (token, ref) {\n+    if (!token) return\n+    var node = this.root\n+\n+    for (var i = 0; i < token.length; i++) {\n+      if (!(token[i] in node)) return\n+      node = node[token[i]]\n+    }\n+\n+    delete node.docs[ref]\n+  }\n+\n+  /**\n+   * Find all the possible suffixes of the passed token using tokens\n+   * currently in the store.\n+   *\n+   * @param {String} token The token to expand.\n+   * @returns {Array}\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.expand = function (token, memo) {\n+    var root = this.getNode(token),\n+        docs = root.docs || {},\n+        memo = memo || []\n+\n+    if (Object.keys(docs).length) memo.push(token)\n+\n+    Object.keys(root)\n+        .forEach(function (key) {\n+          if (key === 'docs') return\n+\n+          memo.concat(this.expand(token + key, memo))\n+        }, this)\n+\n+    return memo\n+  }\n+\n+  /**\n+   * Returns a representation of the token store ready for serialisation.\n+   *\n+   * @returns {Object}\n+   * @memberOf TokenStore\n+   */\n+  lunr.TokenStore.prototype.toJSON = function () {\n+    return {\n+      root: this.root,\n+      length: this.length\n+    }\n+  }\n+\n+\n+  /**\n+   * export the module via AMD, CommonJS or as a browser global\n+   * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n+   */\n+  ;(function (root, factory) {\n+    if (typeof define === 'function' && define.amd) {\n+      // AMD. Register as an anonymous module.\n+      define(factory)","path":"slate/source/javascripts/lib/_lunr.js","position":1890,"original_position":1890,"commit_id":"7a5afd297dd0e5f6a8db766b9af3332f4e619489","original_commit_id":"7a5afd297dd0e5f6a8db766b9af3332f4e619489","user":{"login":"houndci-bot","id":6697940,"avatar_url":"https://avatars0.githubusercontent.com/u/6697940?v=4","gravatar_id":"","url":"https://api.github.com/users/houndci-bot","html_url":"https://github.com/houndci-bot","followers_url":"https://api.github.com/users/houndci-bot/followers","following_url":"https://api.github.com/users/houndci-bot/following{/other_user}","gists_url":"https://api.github.com/users/houndci-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci-bot/subscriptions","organizations_url":"https://api.github.com/users/houndci-bot/orgs","repos_url":"https://api.github.com/users/houndci-bot/repos","events_url":"https://api.github.com/users/houndci-bot/events{/privacy}","received_events_url":"https://api.github.com/users/houndci-bot/received_events","type":"User","site_admin":false},"body":"'define' is not defined                                                       no-undef<br>Missing semicolon                                                             semi","created_at":"2017-12-13T17:43:32Z","updated_at":"2017-12-13T17:43:33Z","html_url":"https://github.com/adesege/HelloBooks/pull/78#discussion_r156731732","pull_request_url":"https://api.github.com/repos/adesege/HelloBooks/pulls/78","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/comments/156731732"},"html":{"href":"https://github.com/adesege/HelloBooks/pull/78#discussion_r156731732"},"pull_request":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/78"}}},"pull_request":{"url":"https://api.github.com/repos/adesege/HelloBooks/pulls/78","id":157969877,"html_url":"https://github.com/adesege/HelloBooks/pull/78","diff_url":"https://github.com/adesege/HelloBooks/pull/78.diff","patch_url":"https://github.com/adesege/HelloBooks/pull/78.patch","issue_url":"https://api.github.com/repos/adesege/HelloBooks/issues/78","number":78,"state":"open","locked":false,"title":"chore(refactor-server-test): refactor server test naming convention","user":{"login":"adesege","id":20769821,"avatar_url":"https://avatars3.githubusercontent.com/u/20769821?v=4","gravatar_id":"","url":"https://api.github.com/users/adesege","html_url":"https://github.com/adesege","followers_url":"https://api.github.com/users/adesege/followers","following_url":"https://api.github.com/users/adesege/following{/other_user}","gists_url":"https://api.github.com/users/adesege/gists{/gist_id}","starred_url":"https://api.github.com/users/adesege/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adesege/subscriptions","organizations_url":"https://api.github.com/users/adesege/orgs","repos_url":"https://api.github.com/users/adesege/repos","events_url":"https://api.github.com/users/adesege/events{/privacy}","received_events_url":"https://api.github.com/users/adesege/received_events","type":"User","site_admin":false},"body":"#### What does this PR do?\r\nThis PR will implement scorecard feedback implementation\r\n\r\n#### Description of Task to be completed?\r\nN/A\r\n\r\n#### How should this be manually tested?\r\nN/A\r\n\r\n#### Any background context you want to provide?\r\nN/A\r\n\r\n#### What are the relevant pivotal tracker stories?\r\n#153550278\r\n\r\n#### Screenshots (if appropriate)\r\nN/A\r\n\r\n#### Questions: \r\nN/A\r\n","created_at":"2017-12-12T23:49:46Z","updated_at":"2017-12-13T17:43:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7b0e470bf589e4b806babac63e24d0f1852201f4","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/adesege/HelloBooks/pulls/78/commits","review_comments_url":"https://api.github.com/repos/adesege/HelloBooks/pulls/78/comments","review_comment_url":"https://api.github.com/repos/adesege/HelloBooks/pulls/comments{/number}","comments_url":"https://api.github.com/repos/adesege/HelloBooks/issues/78/comments","statuses_url":"https://api.github.com/repos/adesege/HelloBooks/statuses/7a5afd297dd0e5f6a8db766b9af3332f4e619489","head":{"label":"adesege:chore/153550278/feedback-implementation","ref":"chore/153550278/feedback-implementation","sha":"7a5afd297dd0e5f6a8db766b9af3332f4e619489","user":{"login":"adesege","id":20769821,"avatar_url":"https://avatars3.githubusercontent.com/u/20769821?v=4","gravatar_id":"","url":"https://api.github.com/users/adesege","html_url":"https://github.com/adesege","followers_url":"https://api.github.com/users/adesege/followers","following_url":"https://api.github.com/users/adesege/following{/other_user}","gists_url":"https://api.github.com/users/adesege/gists{/gist_id}","starred_url":"https://api.github.com/users/adesege/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adesege/subscriptions","organizations_url":"https://api.github.com/users/adesege/orgs","repos_url":"https://api.github.com/users/adesege/repos","events_url":"https://api.github.com/users/adesege/events{/privacy}","received_events_url":"https://api.github.com/users/adesege/received_events","type":"User","site_admin":false},"repo":{"id":98338255,"name":"HelloBooks","full_name":"adesege/HelloBooks","owner":{"login":"adesege","id":20769821,"avatar_url":"https://avatars3.githubusercontent.com/u/20769821?v=4","gravatar_id":"","url":"https://api.github.com/users/adesege","html_url":"https://github.com/adesege","followers_url":"https://api.github.com/users/adesege/followers","following_url":"https://api.github.com/users/adesege/following{/other_user}","gists_url":"https://api.github.com/users/adesege/gists{/gist_id}","starred_url":"https://api.github.com/users/adesege/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adesege/subscriptions","organizations_url":"https://api.github.com/users/adesege/orgs","repos_url":"https://api.github.com/users/adesege/repos","events_url":"https://api.github.com/users/adesege/events{/privacy}","received_events_url":"https://api.github.com/users/adesege/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adesege/HelloBooks","description":"A simple application that helps manage a library and its processes like stocking, tracking and renting books","fork":false,"url":"https://api.github.com/repos/adesege/HelloBooks","forks_url":"https://api.github.com/repos/adesege/HelloBooks/forks","keys_url":"https://api.github.com/repos/adesege/HelloBooks/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adesege/HelloBooks/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adesege/HelloBooks/teams","hooks_url":"https://api.github.com/repos/adesege/HelloBooks/hooks","issue_events_url":"https://api.github.com/repos/adesege/HelloBooks/issues/events{/number}","events_url":"https://api.github.com/repos/adesege/HelloBooks/events","assignees_url":"https://api.github.com/repos/adesege/HelloBooks/assignees{/user}","branches_url":"https://api.github.com/repos/adesege/HelloBooks/branches{/branch}","tags_url":"https://api.github.com/repos/adesege/HelloBooks/tags","blobs_url":"https://api.github.com/repos/adesege/HelloBooks/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adesege/HelloBooks/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adesege/HelloBooks/git/refs{/sha}","trees_url":"https://api.github.com/repos/adesege/HelloBooks/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adesege/HelloBooks/statuses/{sha}","languages_url":"https://api.github.com/repos/adesege/HelloBooks/languages","stargazers_url":"https://api.github.com/repos/adesege/HelloBooks/stargazers","contributors_url":"https://api.github.com/repos/adesege/HelloBooks/contributors","subscribers_url":"https://api.github.com/repos/adesege/HelloBooks/subscribers","subscription_url":"https://api.github.com/repos/adesege/HelloBooks/subscription","commits_url":"https://api.github.com/repos/adesege/HelloBooks/commits{/sha}","git_commits_url":"https://api.github.com/repos/adesege/HelloBooks/git/commits{/sha}","comments_url":"https://api.github.com/repos/adesege/HelloBooks/comments{/number}","issue_comment_url":"https://api.github.com/repos/adesege/HelloBooks/issues/comments{/number}","contents_url":"https://api.github.com/repos/adesege/HelloBooks/contents/{+path}","compare_url":"https://api.github.com/repos/adesege/HelloBooks/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adesege/HelloBooks/merges","archive_url":"https://api.github.com/repos/adesege/HelloBooks/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adesege/HelloBooks/downloads","issues_url":"https://api.github.com/repos/adesege/HelloBooks/issues{/number}","pulls_url":"https://api.github.com/repos/adesege/HelloBooks/pulls{/number}","milestones_url":"https://api.github.com/repos/adesege/HelloBooks/milestones{/number}","notifications_url":"https://api.github.com/repos/adesege/HelloBooks/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adesege/HelloBooks/labels{/name}","releases_url":"https://api.github.com/repos/adesege/HelloBooks/releases{/id}","deployments_url":"https://api.github.com/repos/adesege/HelloBooks/deployments","created_at":"2017-07-25T18:35:25Z","updated_at":"2017-12-07T19:26:23Z","pushed_at":"2017-12-13T17:42:57Z","git_url":"git://github.com/adesege/HelloBooks.git","ssh_url":"git@github.com:adesege/HelloBooks.git","clone_url":"https://github.com/adesege/HelloBooks.git","svn_url":"https://github.com/adesege/HelloBooks","homepage":"http://hellobooks.herokuapp.com","size":13670,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":2,"open_issues":1,"watchers":1,"default_branch":"development"}},"base":{"label":"adesege:development","ref":"development","sha":"2db088836316c095be0e30efaaec4e3301b23255","user":{"login":"adesege","id":20769821,"avatar_url":"https://avatars3.githubusercontent.com/u/20769821?v=4","gravatar_id":"","url":"https://api.github.com/users/adesege","html_url":"https://github.com/adesege","followers_url":"https://api.github.com/users/adesege/followers","following_url":"https://api.github.com/users/adesege/following{/other_user}","gists_url":"https://api.github.com/users/adesege/gists{/gist_id}","starred_url":"https://api.github.com/users/adesege/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adesege/subscriptions","organizations_url":"https://api.github.com/users/adesege/orgs","repos_url":"https://api.github.com/users/adesege/repos","events_url":"https://api.github.com/users/adesege/events{/privacy}","received_events_url":"https://api.github.com/users/adesege/received_events","type":"User","site_admin":false},"repo":{"id":98338255,"name":"HelloBooks","full_name":"adesege/HelloBooks","owner":{"login":"adesege","id":20769821,"avatar_url":"https://avatars3.githubusercontent.com/u/20769821?v=4","gravatar_id":"","url":"https://api.github.com/users/adesege","html_url":"https://github.com/adesege","followers_url":"https://api.github.com/users/adesege/followers","following_url":"https://api.github.com/users/adesege/following{/other_user}","gists_url":"https://api.github.com/users/adesege/gists{/gist_id}","starred_url":"https://api.github.com/users/adesege/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adesege/subscriptions","organizations_url":"https://api.github.com/users/adesege/orgs","repos_url":"https://api.github.com/users/adesege/repos","events_url":"https://api.github.com/users/adesege/events{/privacy}","received_events_url":"https://api.github.com/users/adesege/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adesege/HelloBooks","description":"A simple application that helps manage a library and its processes like stocking, tracking and renting books","fork":false,"url":"https://api.github.com/repos/adesege/HelloBooks","forks_url":"https://api.github.com/repos/adesege/HelloBooks/forks","keys_url":"https://api.github.com/repos/adesege/HelloBooks/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adesege/HelloBooks/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adesege/HelloBooks/teams","hooks_url":"https://api.github.com/repos/adesege/HelloBooks/hooks","issue_events_url":"https://api.github.com/repos/adesege/HelloBooks/issues/events{/number}","events_url":"https://api.github.com/repos/adesege/HelloBooks/events","assignees_url":"https://api.github.com/repos/adesege/HelloBooks/assignees{/user}","branches_url":"https://api.github.com/repos/adesege/HelloBooks/branches{/branch}","tags_url":"https://api.github.com/repos/adesege/HelloBooks/tags","blobs_url":"https://api.github.com/repos/adesege/HelloBooks/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adesege/HelloBooks/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adesege/HelloBooks/git/refs{/sha}","trees_url":"https://api.github.com/repos/adesege/HelloBooks/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adesege/HelloBooks/statuses/{sha}","languages_url":"https://api.github.com/repos/adesege/HelloBooks/languages","stargazers_url":"https://api.github.com/repos/adesege/HelloBooks/stargazers","contributors_url":"https://api.github.com/repos/adesege/HelloBooks/contributors","subscribers_url":"https://api.github.com/repos/adesege/HelloBooks/subscribers","subscription_url":"https://api.github.com/repos/adesege/HelloBooks/subscription","commits_url":"https://api.github.com/repos/adesege/HelloBooks/commits{/sha}","git_commits_url":"https://api.github.com/repos/adesege/HelloBooks/git/commits{/sha}","comments_url":"https://api.github.com/repos/adesege/HelloBooks/comments{/number}","issue_comment_url":"https://api.github.com/repos/adesege/HelloBooks/issues/comments{/number}","contents_url":"https://api.github.com/repos/adesege/HelloBooks/contents/{+path}","compare_url":"https://api.github.com/repos/adesege/HelloBooks/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adesege/HelloBooks/merges","archive_url":"https://api.github.com/repos/adesege/HelloBooks/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adesege/HelloBooks/downloads","issues_url":"https://api.github.com/repos/adesege/HelloBooks/issues{/number}","pulls_url":"https://api.github.com/repos/adesege/HelloBooks/pulls{/number}","milestones_url":"https://api.github.com/repos/adesege/HelloBooks/milestones{/number}","notifications_url":"https://api.github.com/repos/adesege/HelloBooks/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adesege/HelloBooks/labels{/name}","releases_url":"https://api.github.com/repos/adesege/HelloBooks/releases{/id}","deployments_url":"https://api.github.com/repos/adesege/HelloBooks/deployments","created_at":"2017-07-25T18:35:25Z","updated_at":"2017-12-07T19:26:23Z","pushed_at":"2017-12-13T17:42:57Z","git_url":"git://github.com/adesege/HelloBooks.git","ssh_url":"git@github.com:adesege/HelloBooks.git","clone_url":"https://github.com/adesege/HelloBooks.git","svn_url":"https://github.com/adesege/HelloBooks","homepage":"http://hellobooks.herokuapp.com","size":13670,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":2,"open_issues":1,"watchers":1,"default_branch":"development"}},"_links":{"self":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/78"},"html":{"href":"https://github.com/adesege/HelloBooks/pull/78"},"issue":{"href":"https://api.github.com/repos/adesege/HelloBooks/issues/78"},"comments":{"href":"https://api.github.com/repos/adesege/HelloBooks/issues/78/comments"},"review_comments":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/78/comments"},"review_comment":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/adesege/HelloBooks/pulls/78/commits"},"statuses":{"href":"https://api.github.com/repos/adesege/HelloBooks/statuses/7a5afd297dd0e5f6a8db766b9af3332f4e619489"}},"author_association":"OWNER"}}
{"actor":{"display_login":"houndci-bot"}}