text: (function () {
      // Shortcuts
      var C = CryptoJS;
      var C_lib = C.lib;
      var WordArray = C_lib.WordArray;
      var C_enc = C.enc;
  
      /**
       * Base64url encoding strategy.
       */
      var Base64url = C_enc.Base64url = {
          /**
           * Converts a word array to a Base64url string.
           *
           * @param {WordArray} wordArray The word array.
           *
           * @param {boolean} urlSafe Whether to use url safe
           *
           * @return {string} The Base64url string.
           *
           * @static
           *
           * @example
           *
           *     var base64String = CryptoJS.enc.Base64url.stringify(wordArray);
           */
          stringify: function (wordArray, urlSafe) {
              if (urlSafe === undefined) {
                  urlSafe = true
              }
              // Shortcuts
              var words = wordArray.words;
              var sigBytes = wordArray.sigBytes;
              var map = urlSafe ? this._safe_map : this._map;
  
              // Clamp excess bits
              wordArray.clamp();
  
              // Convert
              var base64Chars = [];
              for (var i = 0; i < sigBytes; i += 3) {
                  var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;
                  var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
                  var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
  
                  var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
  
                  for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
                      base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
                  }
              }
  
              // Add padding
              var paddingChar = map.charAt(64);
              if (paddingChar) {
                  while (base64Chars.length % 4) {
                      base64Chars.push(paddingChar);
                  }
              }
  
              return base64Chars.join('');
          },
  
          /**
           * Converts a Base64url string to a word array.
           *
           * @param {string} base64Str The Base64url string.
           *
           * @param {boolean} urlSafe Whether to use url safe
           *
           * @return {WordArray} The word array.
           *
           * @static
           *
           * @example
           *
           *     var wordArray = CryptoJS.enc.Base64url.parse(base64String);
           */
          parse: function (base64Str, urlSafe=true) {
              // Shortcuts
              var base64StrLength = base64Str.length;
              var map = urlSafe ? this._safe_map : this._map;
              var reverseMap = this._reverseMap;
  
              if (!reverseMap) {
                  reverseMap = this._reverseMap = [];
                  for (var j = 0; j < map.length; j++) {
                      reverseMap[map.charCodeAt(j)] = j;
                  }
              }
  
              // Ignore padding
              var paddingChar = map.charAt(64);
              if (paddingChar) {
                  var paddingIndex = base64Str.indexOf(paddingChar);
                  if (paddingIndex !== -1) {
                      base64StrLength = paddingIndex;
                  }
              }
  
              // Convert
              return parseLoop(base64Str, base64StrLength, reverseMap);
  
          },
  
          _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
          _safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
      };
  
      function parseLoop(base64Str, base64StrLength, reverseMap) {
          var words = [];
          var nBytes = 0;
          for (var i = 0; i < base64StrLength; i++) {
              if (i % 4) {
                  var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
                  var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
                  var bitsCombined = bits1 | bits2;
                  words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
                  nBytes++;
              }
          }
          return WordArray.create(words, nBytes);
      }
  }());