text: var StringFilr;
  (function (StringFilr_1) {
      "use strict";
      /**
       * A general utility for retrieving data from an Object based on nested class
       * names. You can think of the internal "library" Object as a tree structure,
       * such that you can pass in a listing (in any order) of the path to data for
       * retrieval.
       */
      var StringFilr = /** @class */ (function () {
          /**
           * @param {IStringFilrSettings} settings
           */
          function StringFilr(settings) {
              if (!settings) {
                  throw new Error("No settings given to StringFilr.");
              }
              if (!settings.library) {
                  throw new Error("No library given to StringFilr.");
              }
              this.library = settings.library;
              this.normal = settings.normal;
              this.requireNormalKey = settings.requireNormalKey;
              this.cache = {};
              if (this.requireNormalKey) {
                  if (typeof this.normal === "undefined") {
                      throw new Error("StringFilr is given requireNormalKey, but no normal class.");
                  }
                  this.ensureLibraryNormal();
              }
          }
          /**
           * @return {Object} The base library of stored information.
           */
          StringFilr.prototype.getLibrary = function () {
              return this.library;
          };
          /**
           * @return {String} The optional normal class String.
           */
          StringFilr.prototype.getNormal = function () {
              return this.normal;
          };
          /**
           * @return {Object} The complete cache of cached output.
           */
          StringFilr.prototype.getCache = function () {
              return this.cache;
          };
          /**
           * @return {Mixed} A cached value, if it exists/
           */
          StringFilr.prototype.getCached = function (key) {
              return this.cache[key];
          };
          /**
           * Completely clears the cache Object.
           */
          StringFilr.prototype.clearCache = function () {
              this.cache = {};
          };
          /**
           * Clears the cached entry for a key.
           *
           * @param {String} key
           */
          StringFilr.prototype.clearCached = function (key) {
              delete this.cache[key];
              if (this.normal) {
                  delete this.cache[key.replace(this.normal, "")];
              }
          };
          /**
           * Retrieves the deepest matching data in the library for a key.
           *
           * @param {String} keyRaw
           * @return {Mixed}
           */
          StringFilr.prototype.get = function (keyRaw) {
              var key, result;
              if (this.normal) {
                  key = keyRaw.replace(this.normal, "");
              }
              else {
                  key = keyRaw;
              }
              // Quickly return a cached result if it exists
              if (this.cache.hasOwnProperty(key)) {
                  return this.cache[key];
              }
              // Since no existed, it must be found deep within the library
              result = this.followClass(key.split(/\s+/g), this.library);
              this.cache[key] = this.cache[keyRaw] = result;
              return result;
          };
          /**
           * Utility helper to recursively check for tree branches in the library
           * that don't have a key equal to the normal. For each sub-directory that
           * is caught, the path to it is added to output.
           *
           * @param {Object} current   The current location being searched within
           *                           the library.
           * @param {String} path   The current path within the library.
           * @param {String[]} output   An Array of the String paths to parts that
           *                           don't have a matching key.
           * @return {String[]} output
           */
          StringFilr.prototype.findLackingNormal = function (current, path, output) {
              var i;
              if (!current.hasOwnProperty(this.normal)) {
                  output.push(path);
              }
              if (typeof current[i] === "object") {
                  for (i in current) {
                      if (current.hasOwnProperty(i)) {
                          this.findLackingNormal(current[i], path + " " + i, output);
                      }
                  }
              }
              return output;
          };
          /**
           * Utility function to follow a path into the library (this is the driver
           * for searching into the library). For each available key, if it matches
           * a key in current, it is removed from keys and recursion happens on the
           * sub-directory in current.
           *
           * @param {String[]} keys   The currently available keys to search within.
           * @param {Object} current   The current location being searched within
           *                           the library.
           * @return {Mixed} The most deeply matched part of the library.
           */
          StringFilr.prototype.followClass = function (keys, current) {
              var key, i;
              // If keys runs out, we're done
              if (!keys || !keys.length) {
                  return current;
              }
              // For each key in the current array...
              for (i = 0; i < keys.length; i += 1) {
                  key = keys[i];
                  // ...if it matches, recurse on the other keys
                  if (current.hasOwnProperty(key)) {
                      keys.splice(i, 1);
                      return this.followClass(keys, current[key]);
                  }
              }
              // If no key matched, try the normal (default)
              if (this.normal && current.hasOwnProperty(this.normal)) {
                  return this.followClass(keys, current[this.normal]);
              }
              // Nothing matches anything; we're done.
              return current;
          };
          /**
           * Driver for this.findLackingNormal. If library directories are found to
           * not have a normal, it throws an error.
           */
          StringFilr.prototype.ensureLibraryNormal = function () {
              var caught = this.findLackingNormal(this.library, "base", []);
              if (caught.length) {
                  throw new Error("Found " + caught.length + " library "
                      + "sub-directories missing the normal: "
                      + "\r\n  " + caught.join("\r\n  "));
              }
          };
          return StringFilr;
      }());
      StringFilr_1.StringFilr = StringFilr;
  })(StringFilr || (StringFilr = {}));
  