text: /*!
   * Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
   * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
   *
   * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *
   * See the License for the specific language governing permissions and limitations under the License.
   */
  /* global window, document, btoa, atob, Uint8Array */
  
  var util = module.exports;
  
  // converts a string to base64 (url/filename safe variant)
  util.stringToBase64Url = function(str) {
    var b64 = btoa(str);
    return util.base64ToBase64Url(b64);
  };
  
  // converts a standard base64-encoded string to a "url/filename safe" variant
  util.base64ToBase64Url = function(b64) {
    return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
  };
  
  // converts a "url/filename safe" base64 string to a "standard" base64 string
  util.base64UrlToBase64 = function(b64u) {
    return b64u.replace(/-/g, '+').replace(/_/g, '/');
  };
  
  util.base64UrlToString = function(b64u) {
    var b64 = util.base64UrlToBase64(b64u);
    switch (b64.length % 4) {
      case 0:
        break;
      case 2:
        b64 += '==';
        break;
      case 3:
        b64 += '=';
        break;
      default:
        throw 'Not a valid Base64Url';
    }
    var utf8 = atob(b64);
    try {
      return decodeURIComponent(escape(utf8));
    } catch (e) {
      return utf8;
    }
  };
  
  util.stringToBuffer = function(str) {
    var buffer = new Uint8Array(str.length);
    for (var i = 0; i < str.length; i++) {
      buffer[i] = str.charCodeAt(i);
    }
    return buffer;
  };
  
  util.base64UrlDecode = function(str) {
    return atob(util.base64UrlToBase64(str));
  };
  
  util.bind = function(fn, ctx) {
    var additionalArgs = Array.prototype.slice.call(arguments, 2);
    return function() {
      var args = Array.prototype.slice.call(arguments);
      args = additionalArgs.concat(args);
      return fn.apply(ctx, args);
    };
  };
  
  util.isAbsoluteUrl = function(url) {
    return /^(?:[a-z]+:)?\/\//i.test(url);
  };
  
  util.isString = function(obj) {
    return Object.prototype.toString.call(obj) === '[object String]';
  };
  
  util.isObject = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
  };
  
  util.isNumber = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Number]';
  };
  
  util.isoToUTCString = function(str) {
    var parts = str.match(/\d+/g),
        isoTime = Date.UTC(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]),
        isoDate = new Date(isoTime);
  
    return isoDate.toUTCString();
  };
  
  util.toQueryParams = function(obj) {
    var str = [];
    if (obj !== null) {
      for (var key in obj) {
        if (obj.hasOwnProperty(key) &&
            obj[key] !== undefined &&
            obj[key] !== null) {
          str.push(key + '=' + encodeURIComponent(obj[key]));
        }
      }
    }
    if (str.length) {
      return '?' + str.join('&');
    } else {
      return '';
    }
  };
  
  util.genRandomString = function(length) {
    var randomCharset = 'abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    var random = '';
    for (var c = 0, cl = randomCharset.length; c < length; ++c) {
      random += randomCharset[Math.floor(Math.random() * cl)];
    }
    return random;
  };
  
  util.extend = function() {
    // First object will be modified!
    var obj1 = arguments[0];
    // Properties from other objects will be copied over
    var objArray = [].slice.call(arguments, 1);
    objArray.forEach(function(obj) {
      for (var prop in obj) {
        // copy over all properties with defined values
        if (obj.hasOwnProperty(prop) && obj[prop] !== undefined) {
          obj1[prop] = obj[prop];
        }
      }
    });
    return obj1; // return the modified object
  };
  
  util.removeNils = function(obj) {
    var cleaned = {};
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        var value = obj[prop];
        if (value !== null && value !== undefined) {
          cleaned[prop] = value;
        }
      }
    }
    return cleaned;
  };
  
  util.clone = function(obj) {
    if (obj) {
      var str = JSON.stringify(obj);
      if (str) {
        return JSON.parse(str);
      }
    }
    return obj;
  };
  
  // Analogous to _.omit
  util.omit = function(obj) {
    var props = Array.prototype.slice.call(arguments, 1);
    var newobj = {};
    for (var p in obj) {
      if (obj.hasOwnProperty(p) && props.indexOf(p) == -1) {
        newobj[p] = obj[p];
      }
    }
    return util.clone(newobj);
  };
  
  util.find = function(collection, searchParams) {
    var c = collection.length;
    while (c--) {
      var item = collection[c];
      var found = true;
      for (var prop in searchParams) {
        if (!searchParams.hasOwnProperty(prop)) {
          continue;
        }
        if (item[prop] !== searchParams[prop]) {
          found = false;
          break;
        }
      }
      if (found) {
        return item;
      }
    }
  };
  
  util.getLink = function(obj, linkName, altName) {
    if (!obj || !obj._links) {
      return;
    }
  
    var link = util.clone(obj._links[linkName]);
  
    // If a link has a name and we have an altName, return if they match
    if (link && link.name && altName) {
      if (link.name === altName) {
        return link;
      }
    } else {
      return link;
    }
  };
  
  util.getNativeConsole = function() {
    if (typeof window !== 'undefined') {
      return window.console;
    } else if (typeof console !== 'undefined') {
      return console;
    } else {
      return undefined;
    }
  };
  
  util.getConsole = function() {
    var nativeConsole = util.getNativeConsole();
    if (nativeConsole && nativeConsole.log) {
      return nativeConsole;
    }
    return {
      log: function() {}
    };
  };
  
  util.warn = function(text) {
    /* eslint-disable no-console */
    util.getConsole().log('[okta-auth-sdk] WARN: ' + text);
    /* eslint-enable */
  };
  
  util.deprecate = function(text) {
    /* eslint-disable no-console */
    util.getConsole().log('[okta-auth-sdk] DEPRECATION: ' + text);
    /* eslint-enable */
  };
  
  util.deprecateWrap = function(text, fn) {
    return function() {
      util.deprecate(text);
      return fn.apply(null, arguments);
    };
  };
  
  util.removeTrailingSlash = function(path) {
    if (!path) {
      return;
    }
    // Remove any whitespace before or after string
    var trimmed = path.replace(/^\s+|\s+$/gm,'');
    // Remove trailing slash(es)
    trimmed = trimmed.replace(/\/+$/, '');
  
    return trimmed;
  };
  
  util.isIE11OrLess = function() {
    return !!document.documentMode && document.documentMode <= 11;
  };
  
  util.isFunction = function(fn) {
    return !!fn && {}.toString.call(fn) === '[object Function]';
  };
  
  util.delay = function(ms) {
    return new Promise(function(resolve) {
      setTimeout(resolve, ms);
    });
  };