diff --git a/Gruntfile.js b/Gruntfile.js index 3f2a2e34..2358ec0e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -106,10 +106,11 @@ module.exports = function(grunt) { }, jsdoc : { dist : { - src: ["src/**/*.js"], - jsdoc: "node_modules/jsdoc/jsdoc.js", + src: ["README.md", "src"], options: { - destination: "doc" + destination: "doc", + recurse: true, + template: "jsdoc.template" } } }, diff --git a/doc/JXG.Util.html b/doc/JXG.Util.html index 8b874660..e9581e2c 100644 --- a/doc/JXG.Util.html +++ b/doc/JXG.Util.html @@ -554,13 +554,13 @@ EXAMPLES:
diff --git a/doc/aes.html b/doc/aes.html index 9e7a35ef..4b6607e6 100644 --- a/doc/aes.html +++ b/doc/aes.html @@ -62,7 +62,7 @@
Source:
@@ -83,6 +83,12 @@ +

Requires

+ + + @@ -105,13 +111,13 @@
diff --git a/doc/aes.js.html b/doc/aes.js.html index 66b892e5..13109d90 100644 --- a/doc/aes.js.html +++ b/doc/aes.js.html @@ -38,7 +38,10 @@ * materials provided with the application or distribution. */ -/** @module crypto/cipher/aes */ +/** + * @requires util + * @module crypto/cipher/aes + */ var util = require('../../util'); @@ -340,23 +343,23 @@ var T4 = [ ]; function B0(x) { - return (x & 255); + return (x & 255); } function B1(x) { - return ((x >> 8) & 255); + return ((x >> 8) & 255); } function B2(x) { - return ((x >> 16) & 255); + return ((x >> 16) & 255); } function B3(x) { - return ((x >> 24) & 255); + return ((x >> 24) & 255); } function F1(x0, x1, x2, x3) { - return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << + return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << 24); } @@ -426,9 +429,9 @@ function keyExpansion(key) { r = 0; t = 0; for (j = 0; - (j < kc) && (r < rounds + 1);) { + (j < kc) && (r < rounds + 1);) { for (; - (j < kc) && (t < 4); j++, t++) { + (j < kc) && (t < 4); j++, t++) { keySched[r][t] = tk[j]; } if (t == 4) { @@ -455,9 +458,9 @@ function keyExpansion(key) { } for (j = 0; - (j < kc) && (r < rounds + 1);) { + (j < kc) && (r < rounds + 1);) { for (; - (j < kc) && (t < 4); j++, t++) { + (j < kc) && (t < 4); j++, t++) { keySched[r][t] = tk[j]; } if (t == 4) { @@ -488,10 +491,10 @@ function AESencrypt(block, ctx) { t2 = b2 ^ ctx.rk[r][2]; t3 = b3 ^ ctx.rk[r][3]; - b0 = T1[t0 & 255] ^ T2[(t1 >> 8) & 255] ^ T3[(t2 >> 16) & 255] ^ T4[t3 >>> 24]; - b1 = T1[t1 & 255] ^ T2[(t2 >> 8) & 255] ^ T3[(t3 >> 16) & 255] ^ T4[t0 >>> 24]; - b2 = T1[t2 & 255] ^ T2[(t3 >> 8) & 255] ^ T3[(t0 >> 16) & 255] ^ T4[t1 >>> 24]; - b3 = T1[t3 & 255] ^ T2[(t0 >> 8) & 255] ^ T3[(t1 >> 16) & 255] ^ T4[t2 >>> 24]; + b0 = T1[t0 & 255] ^ T2[(t1 >> 8) & 255] ^ T3[(t2 >> 16) & 255] ^ T4[t3 >>> 24]; + b1 = T1[t1 & 255] ^ T2[(t2 >> 8) & 255] ^ T3[(t3 >> 16) & 255] ^ T4[t0 >>> 24]; + b2 = T1[t2 & 255] ^ T2[(t3 >> 8) & 255] ^ T3[(t0 >> 16) & 255] ^ T4[t1 >>> 24]; + b3 = T1[t3 & 255] ^ T2[(t0 >> 8) & 255] ^ T3[(t1 >> 16) & 255] ^ T4[t2 >>> 24]; } // last round is special @@ -543,13 +546,13 @@ for (var i in types) {
diff --git a/doc/all_packets.js.html b/doc/all_packets.js.html new file mode 100644 index 00000000..b49a5ff3 --- /dev/null +++ b/doc/all_packets.js.html @@ -0,0 +1,99 @@ + + + + + JSDoc: Source: packet/all_packets.js + + + + + + + + + + +
+ +

Source: packet/all_packets.js

+ + + + + +
+
+
/**
+ * @requires enums
+ * @module packet
+ */
+var enums = require('../enums.js');
+
+// This is pretty ugly, but browserify needs to have the requires explicitly written.
+
+module.exports = {
+  /** @see module:packet/compressed */
+  compressed: require('./compressed.js'),
+  /** @see module:packet/sym_encrypted_integrity_protected */
+  sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'),
+  /** @see module:packet/public_key_encrypted_session_key */
+  public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'),
+  /** @see module:packet/sym_encrypted_session_key */
+  sym_encrypted_session_key: require('./sym_encrypted_session_key.js'),
+  /** @see module:packet/literal */
+  literal: require('./literal.js'),
+  /** @see module:packet/public_key */
+  public_key: require('./public_key.js'),
+  /** @see module:packet/symmetrically_encrypted */
+  symmetrically_encrypted: require('./symmetrically_encrypted.js'),
+  /** @see module:packet/marker */
+  marker: require('./marker.js'),
+  /** @see module:packet/public_subkey */
+  public_subkey: require('./public_subkey.js'),
+  /** @see module:packet/user_attribute */
+  user_attribute: require('./user_attribute.js'),
+  /** @see module:packet/one_pass_signature */
+  one_pass_signature: require('./one_pass_signature.js'),
+  /** @see module:packet/secret_key */
+  secret_key: require('./secret_key.js'),
+  /** @see module:packet/userid */
+  userid: require('./userid.js'),
+  /** @see module:packet/secret_subkey */
+  secret_subkey: require('./secret_subkey.js'),
+  /** @see module:packet/signature */
+  signature: require('./signature.js'),
+  /** @see module:packet/trust */
+  trust: require('./trust.js')
+}
+
+for (var i in enums.packet) {
+  var packetClass = module.exports[i];
+
+  if (packetClass != undefined)
+    packetClass.prototype.tag = enums.packet[i];
+}
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/doc/armor.html b/doc/armor.html index 3dfab024..e1b05b12 100644 --- a/doc/armor.html +++ b/doc/armor.html @@ -83,6 +83,16 @@ +

Requires

+ + + @@ -130,7 +140,7 @@
Source:
@@ -154,7 +164,7 @@
-

<inner> armor(messagetype, body, partindex, parttotal) → {String}

+

<static> armor(messagetype, body, partindex, parttotal) → {String}

@@ -307,7 +317,7 @@
Source:
@@ -357,109 +367,7 @@
-

<inner> armor_addheader() → {String}

- - -
-
- - -
- Add additional information to the armor version of an OpenPGP binary -packet block. -
- - - - - - - - - -
- - - -
Version:
-
  • 2011-12-16
- - - - - - - - - -
Author:
-
-
    -
  • Alex
  • -
-
- - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- The header information -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

<inner> dearmor(text) → {Object}

+

<static> dearmor(text) → {Object}

@@ -549,7 +457,7 @@ the encoded bytes
Source:
@@ -600,7 +508,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
-

<inner> get_type(text) → {Integer}

+

<inner> addheader() → {String}

@@ -608,7 +516,8 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
- Finds out which Ascii Armoring type is used. This is an internal function + Add additional information to the armor version of an OpenPGP binary +packet block.
@@ -617,60 +526,15 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
text - - -String - - - - [String] ascii armored text
-
+
Version:
+
  • 2011-12-16
+ @@ -679,6 +543,13 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type +
Author:
+
+
    +
  • Alex
  • +
+
+ @@ -689,7 +560,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
Source:
@@ -714,13 +585,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
- 0 = MESSAGE PART n of m - 1 = MESSAGE PART n - 2 = SIGNED MESSAGE - 3 = PGP MESSAGE - 4 = PUBLIC KEY BLOCK - 5 = PRIVATE KEY BLOCK - null = unknown + The header information
@@ -731,7 +596,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
-Integer +String
@@ -834,7 +699,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
Source:
@@ -884,7 +749,152 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
-

<inner> split_checksum(text) → {Boolean|Object}

+

<inner> getType(text) → {Integer}

+ + +
+
+ + +
+ Finds out which Ascii Armoring type is used. This is an internal function +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
text + + +String + + + + [String] ascii armored text
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ 0 = MESSAGE PART n of m + 1 = MESSAGE PART n + 2 = SIGNED MESSAGE + 3 = PGP MESSAGE + 4 = PUBLIC KEY BLOCK + 5 = PRIVATE KEY BLOCK + null = unknown +
+ + + +
+
+ Type +
+
+ +Integer + + +
+
+ + + + +
+ + + +
+

<inner> splitChecksum(text) → {Boolean|Object}

@@ -973,7 +983,7 @@ an attribute "data" containing the bytes and "type" for the ASCII armor type
Source:
@@ -1028,7 +1038,7 @@ and an attribute "checksum" containing the checksum.
-

<inner> split_headers(text) → {Boolean|Object}

+

<inner> splitHeaders(text) → {Boolean|Object}

@@ -1117,7 +1127,7 @@ and an attribute "checksum" containing the checksum.
Source:
@@ -1285,7 +1295,7 @@ given base64 encoded checksum
Source:
@@ -1348,13 +1358,13 @@ given base64 encoded checksum
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:54 GMT-0800 (PST)
diff --git a/doc/armor.js.html b/doc/armor.js.html index 2e88ab77..f3d3ffe5 100644 --- a/doc/armor.js.html +++ b/doc/armor.js.html @@ -42,11 +42,16 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module encoding/armor */ +/** + * @requires encoding/base64 + * @requires enums + * @requires config + * @module encoding/armor + */ -var base64 = require('./base64.js'); -var enums = require('../enums.js'); -var config = require('../config'); +var base64 = require('./base64.js'), + enums = require('../enums.js'), + config = require('../config'); /** * Finds out which Ascii Armoring type is used. This is an internal function @@ -59,7 +64,7 @@ var config = require('../config'); * 5 = PRIVATE KEY BLOCK * null = unknown */ -function get_type(text) { +function getType(text) { var reHeader = /^-----([^-]+)-----$\n/m; var header = text.match(reHeader); @@ -112,7 +117,7 @@ function get_type(text) { * @version 2011-12-16 * @returns {String} The header information */ -function armor_addheader() { +function addheader() { var result = ""; if (config.show_version) { result += "Version: " + config.versionstring + '\r\n'; @@ -134,8 +139,8 @@ function armor_addheader() { function getCheckSum(data) { var c = createcrc24(data); var str = "" + String.fromCharCode(c >> 16) + - String.fromCharCode((c >> 8) & 0xFF) + - String.fromCharCode(c & 0xFF); + String.fromCharCode((c >> 8) & 0xFF) + + String.fromCharCode(c & 0xFF); return base64.encode(str); } @@ -149,7 +154,7 @@ function getCheckSum(data) { function verifyCheckSum(data, checksum) { var c = getCheckSum(data); var d = checksum; - return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; + return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; } /** * Internal function to calculate a CRC-24 checksum over a given string (data) @@ -196,29 +201,29 @@ function createcrc24(input) { var index = 0; while ((input.length - index) > 16) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 1)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 2)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 3)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 4)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 5)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 6)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 7)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 8)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 9)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 10)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 11)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 12)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 13)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 14)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 15)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 1)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 2)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 3)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 4)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 5)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 6)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 7)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 8)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 9)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 10)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 11)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 12)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 13)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 14)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 15)) & 0xff]; index += 16; } for (var j = index; j < input.length; j++) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff]; } - return crc & 0xffffff; + return crc & 0xffffff; } /** @@ -228,7 +233,7 @@ function createcrc24(input) { * or an object with attribute "headers" containing the headers and * and an attribute "body" containing the body. */ -function split_headers(text) { +function splitHeaders(text) { var reEmptyLine = /^[\t ]*\n/m; var headers = ""; var body = text; @@ -250,7 +255,7 @@ function split_headers(text) { * or an object with attribute "body" containing the body * and an attribute "checksum" containing the checksum. */ -function split_checksum(text) { +function splitChecksum(text) { var reChecksumStart = /^=/m; var body = text; var checksum = ""; @@ -271,13 +276,14 @@ function split_checksum(text) { * @param {String} text OpenPGP armored message * @returns {Object} An object with attribute "text" containing the message text, * an attribute "data" containing the bytes and "type" for the ASCII armor type + * @static */ function dearmor(text) { var reSplit = /^-----[^-]+-----$\n/m; text = text.replace(/\r/g, ''); - var type = get_type(text); + var type = getType(text); if (!type) { throw new Error('Unknow ASCII armor type'); } @@ -296,8 +302,8 @@ function dearmor(text) { } if (type != 2) { - var msg = split_headers(splittext[indexBase]); - var msg_sum = split_checksum(msg.body); + var msg = splitHeaders(splittext[indexBase]); + var msg_sum = splitChecksum(msg.body); result = { data: base64.decode(msg_sum.body), @@ -307,9 +313,9 @@ function dearmor(text) { checksum = msg_sum.checksum; } else { // Reverse dash-escaping for msg and remove trailing whitespace at end of line - var msg = split_headers(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); - var sig = split_headers(splittext[indexBase + 1].replace(/^- /mg, '')); - var sig_sum = split_checksum(sig.body); + var msg = splitHeaders(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); + var sig = splitHeaders(splittext[indexBase + 1].replace(/^- /mg, '')); + var sig_sum = splitChecksum(sig.body); result = { text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"), @@ -338,20 +344,21 @@ function dearmor(text) { * @param {Integer} partindex * @param {Integer} parttotal * @returns {String} Armored text + * @static */ function armor(messagetype, body, partindex, parttotal) { var result = ""; switch (messagetype) { case enums.armor.multipart_section: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; break; case enums.armor.mutlipart_last: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n"; @@ -361,28 +368,28 @@ function armor(messagetype, body, partindex, parttotal) { result += "Hash: " + body.hash + "\r\n\r\n"; result += body.text.replace(/\n-/g, "\n- -"); result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body.data); result += "\r\n=" + getCheckSum(body.data) + "\r\n"; result += "-----END PGP SIGNATURE-----\r\n"; break; case enums.armor.message: result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE-----\r\n"; break; case enums.armor.public_key: result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; break; case enums.armor.private_key: result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; @@ -406,13 +413,13 @@ module.exports = {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/base64.html b/doc/base64.html index 7b2a87e3..2982ade0 100644 --- a/doc/base64.html +++ b/doc/base64.html @@ -62,7 +62,7 @@
Source:
@@ -91,6 +91,288 @@ +

Methods

+ +
+ +
+

<static> r2s(t) → {string}

+ + +
+
+ + +
+ Convert radix-64 to binary string +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
t + + +String + + + + radix-64 string to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ binary version of input string +
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ + + +
+

<static> s2r(t) → {string}

+ + +
+
+ + +
+ Convert binary string to radix-64 +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
t + + +String + + + + binary string to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ radix-64 version of input string +
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + +
+ +
+ @@ -105,13 +387,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:54 GMT-0800 (PST)
diff --git a/doc/base64.js.html b/doc/base64.js.html index 95a414e4..62b552cb 100644 --- a/doc/base64.js.html +++ b/doc/base64.js.html @@ -38,10 +38,18 @@ * provided with the application or distribution. */ -/** @module encoding/base64 */ +/** + * @module encoding/base64 + */ var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +/** + * Convert binary string to radix-64 + * @param {String} t binary string to convert + * @returns {string} radix-64 version of input string + * @static + */ function s2r(t) { var a, c, n; var r = '', @@ -52,17 +60,17 @@ function s2r(t) { for (n = 0; n < tl; n++) { c = t.charCodeAt(n); if (s == 0) { - r += b64s.charAt((c >> 2) & 63); - a = (c & 3) << 4; + r += b64s.charAt((c >> 2) & 63); + a = (c & 3) << 4; } else if (s == 1) { - r += b64s.charAt((a | (c >> 4) & 15)); - a = (c & 15) << 2; + r += b64s.charAt((a | (c >> 4) & 15)); + a = (c & 15) << 2; } else if (s == 2) { - r += b64s.charAt(a | ((c >> 6) & 3)); + r += b64s.charAt(a | ((c >> 6) & 3)); l += 1; if ((l % 60) == 0) r += "\n"; - r += b64s.charAt(c & 63); + r += b64s.charAt(c & 63); } l += 1; if ((l % 60) == 0) @@ -89,6 +97,12 @@ function s2r(t) { return r; } +/** + * Convert radix-64 to binary string + * @param {String} t radix-64 string to convert + * @returns {string} binary version of input string + * @static + */ function r2s(t) { var c, n; var r = '', @@ -100,9 +114,9 @@ function r2s(t) { c = b64s.indexOf(t.charAt(n)); if (c >= 0) { if (s) - r += String.fromCharCode(a | (c >> (6 - s)) & 255); - s = (s + 2) & 7; - a = (c << s) & 255; + r += String.fromCharCode(a | (c >> (6 - s)) & 255); + s = (s + 2) & 7; + a = (c << s) & 255; } } return r; @@ -122,13 +136,13 @@ module.exports = {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/blowfish.html b/doc/blowfish.html index 9f4925fc..72cd907b 100644 --- a/doc/blowfish.html +++ b/doc/blowfish.html @@ -62,7 +62,7 @@
Source:
@@ -105,13 +105,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST)
diff --git a/doc/blowfish.js.html b/doc/blowfish.js.html index ce9bc865..9b6df5ca 100644 --- a/doc/blowfish.js.html +++ b/doc/blowfish.js.html @@ -30,7 +30,9 @@ * Originally written by nklein software (nklein.com) */ -/** @module crypto/cipher/blowfish */ +/** + * @module crypto/cipher/blowfish + */ /* * Javascript implementation based on Bruce Schneier's reference implementation. @@ -250,13 +252,13 @@ Blowfish.prototype.NN = 16; //* //* This function is needed to get rid of problems //* with the high-bit getting set. If we don't do -//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not -//* equal to ( bb & 0x00FFFFFFFF ) even when they +//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not +//* equal to ( bb & 0x00FFFFFFFF ) even when they //* agree bit-for-bit for the first 32 bits. //* Blowfish.prototype._clean = function(xx) { if (xx < 0) { - var yy = xx & 0x7FFFFFFF; + var yy = xx & 0x7FFFFFFF; xx = yy + 0x80000000; } return xx; @@ -272,13 +274,13 @@ Blowfish.prototype._F = function(xx) { var dd; var yy; - dd = xx & 0x00FF; + dd = xx & 0x00FF; xx >>>= 8; - cc = xx & 0x00FF; + cc = xx & 0x00FF; xx >>>= 8; - bb = xx & 0x00FF; + bb = xx & 0x00FF; xx >>>= 8; - aa = xx & 0x00FF; + aa = xx & 0x00FF; yy = this.sboxes[0][aa] + this.sboxes[1][bb]; yy = yy ^ this.sboxes[2][cc]; @@ -327,16 +329,16 @@ Blowfish.prototype.encrypt_block = function(vector) { var vals = [0, 0]; var off = this.BLOCKSIZE / 2; for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { - vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF); - vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF); + vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF); + vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF); } this._encrypt_block(vals); var ret = []; for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { - ret[ii + 0] = (vals[0] >>> (24 - 8 * (ii)) & 0x00FF); - ret[ii + off] = (vals[1] >>> (24 - 8 * (ii)) & 0x00FF); + ret[ii + 0] = (vals[0] >>> (24 - 8 * (ii)) & 0x00FF); + ret[ii + off] = (vals[1] >>> (24 - 8 * (ii)) & 0x00FF); // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); } @@ -383,7 +385,7 @@ Blowfish.prototype.init = function(key) { var data = 0x00000000; var kk; for (kk = 0; kk < 4; ++kk) { - data = (data << 8) | (key[jj] & 0x00FF); + data = (data << 8) | (key[jj] & 0x00FF); if (++jj >= key.length) { jj = 0; } @@ -449,13 +451,13 @@ module.exports.blockSize = BF.prototype.blockSize = 16;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/cast5.html b/doc/cast5.html index 7e0f5e64..43e26396 100644 --- a/doc/cast5.html +++ b/doc/cast5.html @@ -105,13 +105,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST)
diff --git a/doc/cast5.js.html b/doc/cast5.js.html index f9beac23..2803f34b 100644 --- a/doc/cast5.js.html +++ b/doc/cast5.js.html @@ -134,14 +134,14 @@ function openpgp_symenc_cast5() { r = l ^ f1(r, this.masking[15], this.rotate[15]); l = t; - dst[i] = (r >>> 24) & 255; - dst[i + 1] = (r >>> 16) & 255; - dst[i + 2] = (r >>> 8) & 255; - dst[i + 3] = r & 255; - dst[i + 4] = (l >>> 24) & 255; - dst[i + 5] = (l >>> 16) & 255; - dst[i + 6] = (l >>> 8) & 255; - dst[i + 7] = l & 255; + dst[i] = (r >>> 24) & 255; + dst[i + 1] = (r >>> 16) & 255; + dst[i + 2] = (r >>> 8) & 255; + dst[i + 3] = r & 255; + dst[i + 4] = (l >>> 24) & 255; + dst[i + 5] = (l >>> 16) & 255; + dst[i + 6] = (l >>> 8) & 255; + dst[i + 7] = l & 255; } return dst; @@ -207,14 +207,14 @@ function openpgp_symenc_cast5() { r = l ^ f1(r, this.masking[0], this.rotate[0]); l = t; - dst[i] = (r >>> 24) & 255; - dst[i + 1] = (r >>> 16) & 255; - dst[i + 2] = (r >>> 8) & 255; - dst[i + 3] = r & 255; - dst[i + 4] = (l >>> 24) & 255; - dst[i + 5] = (l >> 16) & 255; - dst[i + 6] = (l >> 8) & 255; - dst[i + 7] = l & 255; + dst[i] = (r >>> 24) & 255; + dst[i + 1] = (r >>> 16) & 255; + dst[i + 2] = (r >>> 8) & 255; + dst[i + 3] = r & 255; + dst[i + 4] = (l >>> 24) & 255; + dst[i + 5] = (l >> 16) & 255; + dst[i + 6] = (l >> 8) & 255; + dst[i + 7] = l & 255; } return dst; @@ -293,22 +293,22 @@ function openpgp_symenc_cast5() { var a = scheduleA[round][j]; var w = t[a[1]]; - w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff]; - w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff]; - w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff]; - w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff]; - w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff]; + w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff]; + w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff]; + w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff]; + w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff]; + w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff]; t[a[0]] = w; } for (var j = 0; j < 4; j++) { var b = scheduleB[round][j]; - var w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff]; + var w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff]; - w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff]; - w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff]; - w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff]; - w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff]; + w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff]; + w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff]; + w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff]; + w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff]; k[ki] = w; ki++; } @@ -317,7 +317,7 @@ function openpgp_symenc_cast5() { for (var i = 0; i < 16; i++) { this.masking[i] = k[i]; - this.rotate[i] = k[16 + i] & 0x1f; + this.rotate[i] = k[16 + i] & 0x1f; } }; @@ -326,19 +326,19 @@ function openpgp_symenc_cast5() { function f1(d, m, r) { var t = m + d; var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255]; + return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255]; } function f2(d, m, r) { var t = m ^ d; var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255]; + return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255]; } function f3(d, m, r) { var t = m - d; var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255]; + return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255]; } var sBox = new Array(8); @@ -640,13 +640,13 @@ module.exports.keySize = cast5.prototype.keySize = 16;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/cfb.html b/doc/cfb.html index 238b1e77..89145bed 100644 --- a/doc/cfb.html +++ b/doc/cfb.html @@ -62,7 +62,7 @@
Source:
@@ -83,6 +83,14 @@ +

Requires

+ + + @@ -96,7 +104,7 @@
-

<static> decrypt(blockcipherfn, block_size, plaintext, key, resync) → {String}

+

<static> decrypt(cipherfn, key, ciphertext, resync) → {String}

@@ -139,54 +147,7 @@ blockcipher to decrypt a message - blockcipherfn - - - - - -openpgp_block_cipher_fn - - - - - - - - - - The algorithm _encrypt_ function to encrypt - data in one block_size encryption. - - - - - - - block_size - - - - - -Integer - - - - - - - - - - the block size in bytes of the algorithm used - - - - - - - plaintext + cipherfn @@ -202,7 +163,8 @@ blockcipher to decrypt a message - ciphertext to be decrypted provided as a string + the algorithm cipher class to decrypt + data in one block_size encryption, @see module:crypto/cipher. @@ -215,7 +177,7 @@ blockcipher to decrypt a message -openpgp_byte_array +String @@ -225,8 +187,31 @@ blockcipher to decrypt a message - key to be used to decrypt the ciphertext. This will be passed to the - blockcipherfn + binary string representation of key to be used to decrypt the ciphertext. +This will be passed to the cipherfn + + + + + + + ciphertext + + + + + +String + + + + + + + + + + to be decrypted provided as a string @@ -249,7 +234,7 @@ blockcipher to decrypt a message - a boolean value specifying if a resync of the + a boolean value specifying if a resync of the IV should be used or not. The encrypteddatapacket uses the "old" style with a resync. Decryption within an encryptedintegrityprotecteddata packet is not resyncing the IV. @@ -283,7 +268,7 @@ blockcipher to decrypt a message
Source:
@@ -333,7 +318,7 @@ blockcipher to decrypt a message
-

<static> encrypt(prefixrandom, blockcipherfn, block_size, plaintext, key, resync) → {String}

+

<static> encrypt(prefixrandom, cipherfn, plaintext, key, resync) → {String}

@@ -400,13 +385,13 @@ using the specified blockcipher to encrypt a message - blockcipherfn + cipherfn -openpgp_block_cipher_fn +String @@ -416,31 +401,8 @@ using the specified blockcipher to encrypt a message - the algorithm encrypt function to encrypt - data in one block_size encryption. - - - - - - - block_size - - - - - -Integer - - - - - - - - - - the block size in bytes of the algorithm used + the algorithm cipher class to encrypt + data in one block_size encryption, @see module:crypto/cipher. @@ -476,7 +438,7 @@ using the specified blockcipher to encrypt a message -openpgp_byte_array +String @@ -486,8 +448,8 @@ using the specified blockcipher to encrypt a message - key to be used to encrypt the data. This will be passed to the - blockcipherfn + binary string representation of key to be used to encrypt the plaintext. +This will be passed to the cipherfn @@ -510,7 +472,7 @@ using the specified blockcipher to encrypt a message - a boolean value specifying if a resync of the + a boolean value specifying if a resync of the IV should be used or not. The encrypteddatapacket uses the "old" style with a resync. Encryption within an encryptedintegrityprotecteddata packet is not resyncing the IV. @@ -544,7 +506,7 @@ using the specified blockcipher to encrypt a message
Source:
@@ -594,7 +556,7 @@ using the specified blockcipher to encrypt a message
-

<static> mdc(block_size, key, ciphertext) → {String}

+

<static> mdc(key, ciphertext) → {String}

@@ -642,7 +604,7 @@ using the specified blockcipher to encrypt a message -openpgp_block_cipher_fn +String @@ -652,30 +614,7 @@ using the specified blockcipher to encrypt a message - Cipher function to use - - - - - - - block_size - - - - - -Integer - - - - - - - - - - Blocksize of the algorithm + Cipher function to use, @@ -688,7 +627,7 @@ using the specified blockcipher to encrypt a message -openpgp_byte_array +String @@ -698,7 +637,8 @@ using the specified blockcipher to encrypt a message - The key for encryption + binary string representation of key to be used to check the mdc +This will be passed to the cipherfn @@ -752,13 +692,20 @@ using the specified blockcipher to encrypt a message
Source:
+
See:
+
+
    +
  • module:crypto/cipher.
  • +
+
+
@@ -815,13 +762,13 @@ using the specified blockcipher to encrypt a message
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/cfb.js.html b/doc/cfb.js.html index 658567e1..15be6066 100644 --- a/doc/cfb.js.html +++ b/doc/cfb.js.html @@ -42,40 +42,28 @@ * materials provided with the application or distribution. */ -/** @module crypto/cfb */ +/** + * @requires crypto/cipher + * @requires util + * @module crypto/cfb + */ var util = require('../util'), cipher = require('./cipher'); module.exports = { - /** - * An array of bytes, that is integers with values from 0 to 255 - * @typedef {(Array|Uint8Array)} openpgp_byte_array - */ - - /** - * Block cipher function - * @callback openpgp_block_cipher_fn - * @param {openpgp_byte_array} block A block to perform operations on - * @param {openpgp_byte_array} key to use in encryption/decryption - * @return {openpgp_byte_array} Encrypted/decrypted block - */ - - - // -------------------------------------- /** * This function encrypts a given with the specified prefixrandom * using the specified blockcipher to encrypt a message * @param {String} prefixrandom random bytes of block_size length provided * as a string to be used in prefixing the data - * @param {openpgp_block_cipher_fn} blockcipherfn the algorithm encrypt function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used + * @param {String} cipherfn the algorithm cipher class to encrypt + * data in one block_size encryption, @see module:crypto/cipher. * @param {String} plaintext data to be encrypted provided as a string - * @param {openpgp_byte_array} key key to be used to encrypt the data. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the + * @param {String} key binary string representation of key to be used to encrypt the plaintext. + * This will be passed to the cipherfn + * @param {Boolean} resync a boolean value specifying if a resync of the * IV should be used or not. The encrypteddatapacket uses the * "old" style with a resync. Encryption within an * encryptedintegrityprotecteddata packet is not resyncing the IV. @@ -178,9 +166,10 @@ module.exports = { /** * Decrypts the prefixed data for the Modification Detection Code (MDC) computation - * @param {openpgp_block_cipher_fn} cipherfn.encrypt Cipher function to use - * @param {Integer} block_size Blocksize of the algorithm - * @param {openpgp_byte_array} key The key for encryption + * @param {String} cipherfn.encrypt Cipher function to use, + * @see module:crypto/cipher. + * @param {String} key binary string representation of key to be used to check the mdc + * This will be passed to the cipherfn * @param {String} ciphertext The encrypted data * @return {String} plaintext Data of D(ciphertext) with blocksize length +2 */ @@ -211,13 +200,12 @@ module.exports = { /** * This function decrypts a given plaintext using the specified * blockcipher to decrypt a message - * @param {openpgp_block_cipher_fn} blockcipherfn The algorithm _encrypt_ function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used - * @param {String} plaintext ciphertext to be decrypted provided as a string - * @param {openpgp_byte_array} key key to be used to decrypt the ciphertext. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the + * @param {String} cipherfn the algorithm cipher class to decrypt + * data in one block_size encryption, @see module:crypto/cipher. + * @param {String} key binary string representation of key to be used to decrypt the ciphertext. + * This will be passed to the cipherfn + * @param {String} ciphertext to be decrypted provided as a string + * @param {Boolean} resync a boolean value specifying if a resync of the * IV should be used or not. The encrypteddatapacket uses the * "old" style with a resync. Decryption within an * encryptedintegrityprotecteddata packet is not resyncing the IV. @@ -262,7 +250,7 @@ module.exports = { for (n = block_size + 2; n < ciphertext.length; n += block_size) { ablock = cipherfn.encrypt(iblock); - for (i = 0; i < block_size && i + n < ciphertext.length; i++) { + for (i = 0; i < block_size && i + n < ciphertext.length; i++) { iblock[i] = ciphertext.charCodeAt(n + i); text.push(String.fromCharCode(ablock[i] ^ iblock[i])); } @@ -271,7 +259,7 @@ module.exports = { for (i = 0; i < block_size; i++) iblock[i] = ciphertext.charCodeAt(i); for (n = block_size; n < ciphertext.length; n += block_size) { ablock = cipherfn.encrypt(iblock); - for (i = 0; i < block_size && i + n < ciphertext.length; i++) { + for (i = 0; i < block_size && i + n < ciphertext.length; i++) { iblock[i] = ciphertext.charCodeAt(n + i); text.push(String.fromCharCode(ablock[i] ^ iblock[i])); } @@ -346,13 +334,13 @@ module.exports = {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/cipher.html b/doc/cipher.html new file mode 100644 index 00000000..170d25ee --- /dev/null +++ b/doc/cipher.html @@ -0,0 +1,421 @@ + + + + + JSDoc: Module: crypto/cipher + + + + + + + + + + +
+ +

Module: crypto/cipher

+ + + + + +
+ +
+

+ crypto/cipher +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + +

Requires

+ + + + + + + + + +

Members

+ +
+ +
+

<static> blowfish

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> cast5

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> des

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> originalDes

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> twofish

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ +
+ + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/cleartext.js.html b/doc/cleartext.js.html index c7e9b9c8..d2f4b8bc 100644 --- a/doc/cleartext.js.html +++ b/doc/cleartext.js.html @@ -42,12 +42,18 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module cleartext */ +/** + * @requires config + * @requires encoding/armor + * @requires enums + * @requires packet + * @module cleartext + */ -var config = require('./config'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); +var config = require('./config'), + packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'); /** * @class @@ -154,6 +160,7 @@ CleartextMessage.prototype.armor = function() { * reads an OpenPGP cleartext signed message and returns a CleartextMessage object * @param {String} armoredText text to be parsed * @return {module:cleartext~CleartextMessage} new cleartext message object + * @static */ function readArmored(armoredText) { var input = armor.decode(armoredText); @@ -178,13 +185,13 @@ exports.readArmored = readArmored;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/compressed.html b/doc/compressed.html index 68d273b0..08cf71d8 100644 --- a/doc/compressed.html +++ b/doc/compressed.html @@ -36,8 +36,15 @@
+
Implementation of the Compressed Data Packet (Tag 8)
+
+RFC4880 5.6: The Compressed Data packet contains compressed data. Typically, +this packet is found as the contents of an encrypted packet, or following +a Signature or One-Pass Signature packet, and contains a literal data packet.
+ +
-

new require("packet/compressed")()

+

new (require("packet/compressed"))()

@@ -74,7 +81,7 @@
Source:
@@ -148,6 +155,16 @@ +

Requires

+ + + @@ -165,6 +182,10 @@
+
+ Compression algorithm +
+
Type:
@@ -201,7 +222,71 @@
Source:
+ + + + + + + +
+ + + + + + + +
+

compressed :String

+ + +
+
+ +
+ Compressed packet data +
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
@@ -225,6 +310,10 @@
+
+ List of packets +
+
Type:
@@ -261,7 +350,7 @@
Source:
@@ -285,7 +374,7 @@
-

compress(type, data) → {String}

+

compress()

@@ -302,6 +391,145 @@ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

decompress()

+ + +
+
+ + +
+ Decompression method for decompressing the compressed data +read by read_packet +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

read(bytes)

+ + +
+
+ + +
+ Parsing function for the packet. +
+ + + + + + +
Parameters:
@@ -327,30 +555,7 @@ - type - - - - - -Integer - - - - - - - - - - Algorithm to be used // See RFC 4880 9.3 - - - - - - - data + bytes @@ -366,7 +571,7 @@ - Data to be compressed + Payload of a tag 8 packet @@ -397,7 +602,7 @@
Source:
@@ -418,28 +623,6 @@ -
Returns:
- - -
- The compressed data stored in attribute compressedData -
- - - -
-
- Type -
-
- -String - - -
-
- - @@ -447,7 +630,7 @@
-

decompress() → {String}

+

write() → {String}

@@ -455,8 +638,7 @@
- Decompression method for decompressing the compressed data -read by read_packet + Return the compressed packet.
@@ -514,7 +696,7 @@ read by read_packet
- The decompressed data + binary compressed packet
@@ -534,192 +716,6 @@ read by read_packet - - - - -
-

read(input, position, len) → {module:packet/compressed}

- - -
-
- - -
- Parsing function for the packet. -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
input - - -String - - - - Payload of a tag 8 packet
position - - -Integer - - - - Position to start reading from the input string
len - - -Integer - - - - length of the packet or the remaining length of -input at position
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Object representation -
- - - -
-
- Type -
-
- -module:packet/compressed - - -
-
- - - -
@@ -738,13 +734,13 @@ input at position
diff --git a/doc/compressed.js.html b/doc/compressed.js.html index 2838d321..dd8ac616 100644 --- a/doc/compressed.js.html +++ b/doc/compressed.js.html @@ -42,38 +42,47 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/compressed */ +/** + * Implementation of the Compressed Data Packet (Tag 8)<br/> + * <br/> + * RFC4880 5.6: The Compressed Data packet contains compressed data. Typically, + * this packet is found as the contents of an encrypted packet, or following + * a Signature or One-Pass Signature packet, and contains a literal data packet. + * @requires compression/jxg + * @requires encoding/base64 + * @requires enums + * @module packet/compressed + */ var enums = require('../enums.js'), JXG = require('../compression/jxg.js'), base64 = require('../encoding/base64.js'); /** - * @class - * @classdesc Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. + * @constructor */ -module.exports = function packet_compressed() { - /** @type {module:packet/packetlist} */ - this.packets; - /** @type {compression} */ +module.exports = function () { + /** + * List of packets + * @type {module:packet/packetlist} + */ + this.packets = null; + /** + * Compression algorithm + * @type {compression} + */ this.algorithm = 'uncompressed'; + /** + * Compressed packet data + * @type {String} + */ this.compressed = null; /** * Parsing function for the packet. - * @param {String} input Payload of a tag 8 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of - * input at position - * @return {module:packet/compressed} Object representation + * @param {String} bytes Payload of a tag 8 packet */ this.read = function(bytes) { // One octet that gives the algorithm used to compress the packet. @@ -87,6 +96,10 @@ module.exports = function packet_compressed() { + /** + * Return the compressed packet. + * @return {String} binary compressed packet + */ this.write = function() { if (this.compressed == null) this.compress(); @@ -98,7 +111,6 @@ module.exports = function packet_compressed() { /** * Decompression method for decompressing the compressed data * read by read_packet - * @return {String} The decompressed data */ this.decompress = function() { var decompressed; @@ -155,9 +167,6 @@ module.exports = function packet_compressed() { /** * Compress the packet data (member decompressedData) - * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 - * @param {String} data Data to be compressed - * @return {String} The compressed data stored in attribute compressedData */ this.compress = function() { switch (this.algorithm) { @@ -200,13 +209,13 @@ module.exports = function packet_compressed() {
diff --git a/doc/config-config.html b/doc/config-config.html deleted file mode 100644 index eb8dc336..00000000 --- a/doc/config-config.html +++ /dev/null @@ -1,457 +0,0 @@ - - - - - JSDoc: Class: config - - - - - - - - - - -
- -

Class: config

- - - - - -
- -
-

- config/config~ - - config -

- -
Implementation of the GPG4Browsers config object
- -
- -
-
- - - - -
-

new config()

- - -
-
- - -
- This object contains configuration values and implements -storing and retrieving configuration them from HTML5 local storage. - -This object can be accessed after calling openpgp.init() -using openpgp.config -Stored config parameters can be accessed using -openpgp.config.config -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - -

Members

- -
- -
-

debug

- - -
-
- -
- If enabled, debug messages will be printed -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

prefer_hash_algorithm

- - -
-
- - - - - -
- - -
Properties:
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
prefer_hash_algorithm - - -Integer - - - -
encryption_cipher - - -Integer - - - -
compression - - -Integer - - - -
show_version - - -Boolean - - - -
show_comment - - -Boolean - - - -
integrity_protect - - -Boolean - - - -
keyserver - - -String - - - -
- - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- -
- - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/doc/config.html b/doc/config.html index abc43742..97f2f3a1 100644 --- a/doc/config.html +++ b/doc/config.html @@ -38,11 +38,225 @@ +
This object contains configuration values.
+
+
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
prefer_hash_algorithm + + +Integer + + + +
encryption_cipher + + +Integer + + + +
compression + + +Integer + + + +
show_version + + +Boolean + + + +
show_comment + + +Boolean + + + +
integrity_protect + + +Boolean + + + +
keyserver + + +String + + + +
debug + + +Boolean + + + + If enabled, debug messages will be printed
+ + + @@ -83,14 +297,13 @@ - - -

Classes

+

Requires

-
-
config
-
-
+ + + @@ -112,13 +325,13 @@
diff --git a/doc/config.js.html b/doc/config.js.html index 10bed3cf..f8a79b34 100644 --- a/doc/config.js.html +++ b/doc/config.js.html @@ -42,51 +42,36 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module config/config */ +/** + * This object contains configuration values. + * @requires enums + * @property {Integer} prefer_hash_algorithm + * @property {Integer} encryption_cipher + * @property {Integer} compression + * @property {Boolean} show_version + * @property {Boolean} show_comment + * @property {Boolean} integrity_protect + * @property {String} keyserver + * @property {Boolean} debug If enabled, debug messages will be printed + * @module config/config + */ var enums = require('../enums.js'); -/** - * - * This object contains configuration values and implements - * storing and retrieving configuration them from HTML5 local storage. - * - * This object can be accessed after calling openpgp.init() - * using openpgp.config - * Stored config parameters can be accessed using - * openpgp.config.config - * @class - * @classdesc Implementation of the GPG4Browsers config object - */ -var config = function() { - /** - * @property {Integer} prefer_hash_algorithm - * @property {Integer} encryption_cipher - * @property {Integer} compression - * @property {Boolean} show_version - * @property {Boolean} show_comment - * @property {Boolean} integrity_protect - * @property {String} keyserver - */ - this.prefer_hash_algorithm = enums.hash.sha256; - this.encryption_cipher = enums.symmetric.aes256; - this.compression = enums.compression.zip; - this.show_version = true; - this.show_comment = true; - this.integrity_protect = true; - this.keyserver = "keyserver.linux.it"; // "pgp.mit.edu:11371" +module.exports = { + prefer_hash_algorithm: enums.hash.sha256, + encryption_cipher: enums.symmetric.aes256, + compression: enums.compression.zip, + show_version: true, + show_comment: true, + integrity_protect: true, + keyserver: "keyserver.linux.it", // "pgp.mit.edu:11371" - this.versionstring = "OpenPGP.js VERSION"; - this.commentstring = "http://openpgpjs.org"; - - /** - * If enabled, debug messages will be printed - */ - this.debug = false; + versionstring: "OpenPGP.js VERSION", + commentstring: "http://openpgpjs.org", + debug: false }; - -module.exports = new config(); @@ -97,13 +82,13 @@ module.exports = new config();
diff --git a/doc/config.localStorage.js.html b/doc/config.localStorage.js.html deleted file mode 100644 index e86a3283..00000000 --- a/doc/config.localStorage.js.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - JSDoc: Source: config/config.localStorage.js - - - - - - - - - - -
- -

Source: config/config.localStorage.js

- - - - - -
-
-
/** @module config/config_localStorage */
-
-/**
- *
- * This object storing and retrieving configuration from HTML5 local storage.
- *
- * This object can be accessed after calling openpgp.init()
- * @class
- * @classdesc Implementation of the config handler for localstorage
- */
-module.exports = function () {
-
-  /**
-   * Reads the config out of the HTML5 local storage
-   * and initializes the object config.
-   * if config is null the default config will be used
-   */
-  function read() {
-    var cf = JSON.parse(window.localStorage.getItem("config"));
-    if (cf === null) {
-      this.config = this.default_config;
-      this.write();
-    } else
-      this.config = cf;
-  }
-
-  /**
-   * Writes the config to HTML5 local storage
-   */
-  function write() {
-    window.localStorage.setItem("config", JSON.stringify(this.config));
-  }
-
-  this.read = read;
-  this.write = write;
-}
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/doc/config_localStorage.html b/doc/config_localStorage.html deleted file mode 100644 index 88b2f9ba..00000000 --- a/doc/config_localStorage.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - - JSDoc: Module: config/config_localStorage - - - - - - - - - - -
- -

Module: config/config_localStorage

- - - - - -
- -
-

- config/config_localStorage -

- -
- -
-
- - -
-

new require("config/config_localStorage")()

- - -
-
- - -
- This object storing and retrieving configuration from HTML5 local storage. - -This object can be accessed after calling openpgp.init() -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - - - - - - - - - - - -

Methods

- -
- -
-

<inner> read()

- - -
-
- - -
- Reads the config out of the HTML5 local storage -and initializes the object config. -if config is null the default config will be used -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<inner> write()

- - -
-
- - -
- Writes the config to HTML5 local storage -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- -
- - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/doc/crypto.html b/doc/crypto.html index f1580f98..f6f34280 100644 --- a/doc/crypto.html +++ b/doc/crypto.html @@ -83,6 +83,18 @@ +

Requires

+ + + @@ -185,7 +197,7 @@
Source:
@@ -324,7 +336,7 @@
Source:
@@ -464,7 +476,7 @@ size of the cipher
Source:
@@ -675,7 +687,7 @@ of the private key used
Source:
@@ -861,7 +873,7 @@ and the specified algorithm.
Source:
@@ -925,13 +937,13 @@ if elgamal encryption an array of two module:type/mpi is returned; otherwise nul
diff --git a/doc/crypto.js.html b/doc/crypto.js.html index ba190d29..15419cf6 100644 --- a/doc/crypto.js.html +++ b/doc/crypto.js.html @@ -44,7 +44,13 @@ // The GPG4Browsers crypto interface -/** @module crypto/crypto */ +/** + * @requires crypto/cipher + * @requires crypto/public_key + * @requires crypto/random + * @requires type/mpi + * @module crypto/crypto + */ var random = require('./random.js'), cipher = require('./cipher'), @@ -240,8 +246,7 @@ module.exports = { */ generateSessionKey: function(algo) { return random.getRandomBytes(cipher[algo].keySize); - }, - + } }; @@ -253,13 +258,13 @@ module.exports = {
diff --git a/doc/des.html b/doc/des.html index 42f3cd7b..e509398d 100644 --- a/doc/des.html +++ b/doc/des.html @@ -89,6 +89,110 @@ +

Members

+ +
+ +
+

<static> des

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static> originalDes

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ @@ -105,13 +209,13 @@
diff --git a/doc/des.js.html b/doc/des.js.html index e7214352..2f064edf 100644 --- a/doc/des.js.html +++ b/doc/des.js.html @@ -48,9 +48,9 @@ //des //this takes the key, the message, and whether to encrypt or decrypt -/** @module crypto/cipher/des */ - - +/** + * @module crypto/cipher/des + */ function des(keys, message, encrypt, mode, iv, padding) { @@ -158,19 +158,19 @@ function des(keys, message, encrypt, mode, iv, padding) { } //first each 64 but chunk of the message must be permuted according to IP - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((left >>> 16) ^ right) & 0x0000ffff; + temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((right >>> 2) ^ left) & 0x33333333; + temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); @@ -188,9 +188,9 @@ function des(keys, message, encrypt, mode, iv, padding) { //the result is attained by passing these bytes through the S selection functions temp = left; left = right; - right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> - 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & - 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); + right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> + 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & + 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); } temp = left; left = right; @@ -202,19 +202,19 @@ function des(keys, message, encrypt, mode, iv, padding) { right = ((right >>> 1) | (right << 31)); //now perform IP-1, which is IP in the opposite direction - temp = ((left >>> 1) ^ right) & 0x55555555; + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((right >>> 2) ^ left) & 0x33333333; + temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((left >>> 16) ^ right) & 0x0000ffff; + temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); @@ -228,8 +228,8 @@ function des(keys, message, encrypt, mode, iv, padding) { right ^= cbcright2; } } - tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), ( - right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff)); + tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), ( + right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff)); chunk += 8; if (chunk == 512) { @@ -301,32 +301,32 @@ function des_createKeys(key) { left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++); right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((right >>> -16) ^ left) & 0x0000ffff; + temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 2) ^ right) & 0x33333333; + temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2); - temp = ((right >>> -16) ^ left) & 0x0000ffff; + temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 1) ^ right) & 0x55555555; + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); //the right side needs to be shifted and to get the last four bits of the left side - temp = (left << 8) | ((right >>> 20) & 0x000000f0); + temp = (left << 8) | ((right >>> 20) & 0x000000f0); //left needs to be put upside down - left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); + left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); right = temp; //now go through and perform these shifts on the left and right keys @@ -339,20 +339,20 @@ function des_createKeys(key) { left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27); } - left &= -0xf; - right &= -0xf; + left &= -0xf; + right &= -0xf; //now apply PC-2, in such a way that E is easier when encrypting or decrypting //this conversion will look like PC-2 except only the last 6 bits of each byte are used //rather than 48 consecutive bits and the order of lines will be according to //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[( - left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) & + lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[( + left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) & 0xf]; - righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] | - pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] | - pc2bytes13[(right >>> 4) & 0xf]; - temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; + righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] | + pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] | + pc2bytes13[(right >>> 4) & 0xf]; + temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16); } @@ -364,12 +364,12 @@ function des_createKeys(key) { function des_addPadding(message, padding) { var padLength = 8 - (message.length % 8); - if ((padding == 2) && (padLength < 8)) { //pad the message with spaces + if ((padding == 2) && (padLength < 8)) { //pad the message with spaces message += " ".substr(0, padLength); } else if (padding == 1) { //PKCS7 padding message += String.fromCharCode(padLength, padLength, padLength, padLength, padLength, padLength, padLength, padLength).substr(0, padLength); - } else if (!padding && (padLength < 8)) { //pad the message out with null bytes + } else if (!padding && (padLength < 8)) { //pad the message out with null bytes message += "\0\0\0\0\0\0\0\0".substr(0, padLength); } return message; @@ -429,7 +429,9 @@ function OriginalDes(key) { } module.exports = { + /** @static */ des: Des, + /** @static */ originalDes: OriginalDes } @@ -442,13 +444,13 @@ module.exports = {
diff --git a/doc/dsa.html b/doc/dsa.html index 0a03af33..5e5413a6 100644 --- a/doc/dsa.html +++ b/doc/dsa.html @@ -83,6 +83,18 @@ +

Requires

+ + + @@ -105,13 +117,13 @@
diff --git a/doc/dsa.js.html b/doc/dsa.js.html index 9cb81bf1..b9a283a8 100644 --- a/doc/dsa.js.html +++ b/doc/dsa.js.html @@ -44,12 +44,19 @@ // // A Digital signature algorithm implementation -/** @module crypto/public_key/dsa */ +/** + * @requires crypto/hash + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/dsa + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), hashModule = require('../hash'), - util = require('../../util'); + util = require('../../util'), + config = require('../../config'); function DSA() { // s1 = ((g**s) mod p) mod q @@ -72,7 +79,7 @@ function DSA() { } function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; + var usersetting = config.prefer_hash_algorithm; /* * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash @@ -82,21 +89,21 @@ function DSA() { switch (Math.round(q.bitLength() / 8)) { case 20: // 1024 bit - if (usersetting != 2 && - usersetting > 11 && - usersetting != 10 && + if (usersetting != 2 && + usersetting > 11 && + usersetting != 10 && usersetting < 8) return 2; // prefer sha1 return usersetting; case 28: // 2048 bit - if (usersetting > 11 && + if (usersetting > 11 && usersetting < 8) return 11; return usersetting; case 32: // 4096 bit // prefer sha224 - if (usersetting > 10 && + if (usersetting > 10 && usersetting < 8) return 8; // prefer sha256 return usersetting; @@ -135,7 +142,7 @@ function DSA() { var xi; do { xi = new BigInteger(q.bitCount(), rand); - } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1); + } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1); var yi = g.modPow(x, p); return {x: xi, q: qi, p: pi, g: gi, y: yi}; } @@ -160,7 +167,7 @@ function DSA() { var gTemp; do { gTemp = randomfn(bitlength); - } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1); + } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1); return gTemp.modPow(pow, p); } @@ -168,7 +175,7 @@ function DSA() { var tempK; do { tempK = randomfn(bitlength, false); - } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1); + } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1); return tempK; } @@ -199,13 +206,13 @@ module.exports = DSA;
diff --git a/doc/elgamal.html b/doc/elgamal.html index 9979f43b..1bafd57d 100644 --- a/doc/elgamal.html +++ b/doc/elgamal.html @@ -83,6 +83,16 @@ +

Requires

+ + + @@ -105,13 +115,13 @@
diff --git a/doc/elgamal.js.html b/doc/elgamal.js.html index dd12a997..01f752b9 100644 --- a/doc/elgamal.js.html +++ b/doc/elgamal.js.html @@ -44,7 +44,12 @@ // // ElGamal implementation -/** @module crypto/public_key/elgamal */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/elgamal + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), @@ -90,13 +95,13 @@ module.exports = Elgamal;
diff --git a/doc/enums.js.html b/doc/enums.js.html index f09e8e9d..63a74eb8 100644 --- a/doc/enums.js.html +++ b/doc/enums.js.html @@ -25,12 +25,15 @@
-
/** @module enums */
+            
/**
+ * @module enums
+ */
 
 module.exports = {
 
   /** A string to key specifier type
    * @enum {Integer}
+   * @readonly
    */
   s2k: {
     simple: 0,
@@ -41,6 +44,7 @@ module.exports = {
 
   /** RFC4880, section 9.1
    * @enum {Integer}
+   * @readonly
    */
   publicKey: {
     rsa_encrypt_sign: 1,
@@ -52,6 +56,7 @@ module.exports = {
 
   /** RFC4880, section 9.2
    * @enum {Integer}
+   * @readonly
    */
   symmetric: {
     plaintext: 0,
@@ -68,6 +73,7 @@ module.exports = {
 
   /** RFC4880, section 9.3
    * @enum {Integer}
+   * @readonly
    */
   compression: {
     uncompressed: 0,
@@ -80,6 +86,7 @@ module.exports = {
 
   /** RFC4880, section 9.4
    * @enum {Integer}
+   * @readonly
    */
   hash: {
     md5: 1,
@@ -91,9 +98,9 @@ module.exports = {
     sha224: 11
   },
 
-
   /** A list of packet types and numeric tags associated with them.
    * @enum {Integer}
+   * @readonly
    */
   packet: {
     public_key_encrypted_session_key: 1,
@@ -115,9 +122,9 @@ module.exports = {
     modification_detection_code: 19
   },
 
-
   /** Data types in the literal packet
    * @enum {Integer}
+   * @readonly
    */
   literal: {
     /** Binary data 'b' */
@@ -131,41 +138,42 @@ module.exports = {
 
   /** One pass signature packet type
    * @enum {Integer}
+   * @readonly
    */
   signature: {
     /** 0x00: Signature of a binary document. */
     binary: 0,
-    /** 0x01: Signature of a canonical text document.
+    /** 0x01: Signature of a canonical text document.<br/>
      * Canonicalyzing the document by converting line endings. */
     text: 1,
-    /** 0x02: Standalone signature.
+    /** 0x02: Standalone signature.<br/>
      * This signature is a signature of only its own subpacket contents.
      * It is calculated identically to a signature over a zero-lengh
      * binary document.  Note that it doesn't make sense to have a V3
      * standalone signature. */
     standalone: 2,
-    /** 0x10: Generic certification of a User ID and Public-Key packet.
+    /** 0x10: Generic certification of a User ID and Public-Key packet.<br/>
      * The issuer of this certification does not make any particular
      * assertion as to how well the certifier has checked that the owner
      * of the key is in fact the person described by the User ID. */
     cert_generic: 16,
-    /** 0x11: Persona certification of a User ID and Public-Key packet.
+    /** 0x11: Persona certification of a User ID and Public-Key packet.<br/>
      * The issuer of this certification has not done any verification of
      * the claim that the owner of this key is the User ID specified. */
     cert_persona: 17,
-    /** 0x12: Casual certification of a User ID and Public-Key packet.
+    /** 0x12: Casual certification of a User ID and Public-Key packet.<br/>
      * The issuer of this certification has done some casual
      * verification of the claim of identity. */
     cert_casual: 18,
-    /** 0x13: Positive certification of a User ID and Public-Key packet.
+    /** 0x13: Positive certification of a User ID and Public-Key packet.<br/>
      * The issuer of this certification has done substantial
-     * verification of the claim of identity.
-     * 
+     * verification of the claim of identity.<br/>
+     * <br/>
      * Most OpenPGP implementations make their "key signatures" as 0x10
      * certifications.  Some implementations can issue 0x11-0x13
      * certifications, but few differentiate between the types. */
     cert_positive: 19,
-    /** 0x30: Certification revocation signature
+    /** 0x30: Certification revocation signature<br/>
      * This signature revokes an earlier User ID certification signature
      * (signature class 0x10 through 0x13) or direct-key signature
      * (0x1F).  It should be issued by the same key that issued the
@@ -174,7 +182,7 @@ module.exports = {
      * revokes, and should have a later creation date than that
      * certificate. */
     cert_revocation: 48,
-    /** 0x18: Subkey Binding Signature
+    /** 0x18: Subkey Binding Signature<br/>
      * This signature is a statement by the top-level signing key that
      * indicates that it owns the subkey.  This signature is calculated
      * directly on the primary key and subkey, and not on any User ID or
@@ -183,12 +191,12 @@ module.exports = {
      * contains a 0x19 signature made by the signing subkey on the
      * primary key and subkey. */
     subkey_binding: 24,
-    /** 0x19: Primary Key Binding Signature
+    /** 0x19: Primary Key Binding Signature<br/>
      * This signature is a statement by a signing subkey, indicating
      * that it is owned by the primary key and subkey.  This signature
      * is calculated the same way as a 0x18 signature: directly on the
-     * primary key and subkey, and not on any User ID or other packets.
-
+     * primary key and subkey, and not on any User ID or other packets.<br/>
+     * <br/>
      * When a signature is made over a key, the hash data starts with the
      * octet 0x99, followed by a two-octet length of the key, and then body
      * of the key packet.  (Note that this is an old-style packet header for
@@ -197,7 +205,7 @@ module.exports = {
      * the subkey using the same format as the main key (also using 0x99 as
      * the first octet). */
     key_binding: 25,
-    /** 0x1F: Signature directly on a key
+    /** 0x1F: Signature directly on a key<br/>
      * This signature is calculated directly on a key.  It binds the
      * information in the Signature subpackets to the key, and is
      * appropriate to be used for subpackets that provide information
@@ -206,26 +214,27 @@ module.exports = {
      * about the key itself, rather than the binding between a key and a
      * name. */
     key: 31,
-    /** 0x20: Key revocation signature
+    /** 0x20: Key revocation signature<br/>
      * The signature is calculated directly on the key being revoked.  A
      * revoked key is not to be used.  Only revocation signatures by the
      * key being revoked, or by an authorized revocation key, should be
      * considered valid revocation signatures.a */
     key_revocation: 32,
-    /** 0x28: Subkey revocation signature
+    /** 0x28: Subkey revocation signature<br/>
      * The signature is calculated directly on the subkey being revoked.
      * A revoked subkey is not to be used.  Only revocation signatures
      * by the top-level signature key that is bound to this subkey, or
      * by an authorized revocation key, should be considered valid
-     * revocation signatures.
+     * revocation signatures.<br/>
+     * <br/>
      * Key revocation signatures (types 0x20 and 0x28)
      * hash only the key being revoked. */
     subkey_revocation: 40,
-    /** 0x40: Timestamp signature.
+    /** 0x40: Timestamp signature.<br/>
      * This signature is only meaningful for the timestamp contained in
      * it. */
     timestamp: 64,
-    /**    0x50: Third-Party Confirmation signature.
+    /** 0x50: Third-Party Confirmation signature.<br/>
      * This signature is a signature over some other OpenPGP Signature
      * packet(s).  It is analogous to a notary seal on the signed data.
      * A third-party signature SHOULD include Signature Target
@@ -238,6 +247,7 @@ module.exports = {
 
   /** Signature subpacket type
    * @enum {Integer}
+   * @readonly
    */
   signatureSubpacket: {
     signature_creation_time: 2,
@@ -268,28 +278,30 @@ module.exports = {
 
   /** Key flags
    * @enum {Integer}
+   * @readonly
    */
   keyFlags: {
-    // 0x01 - This key may be used to certify other keys.
+    /** 0x01 - This key may be used to certify other keys. */
     certify_keys: 1,
-    // 0x02 - This key may be used to sign data.
+    /** 0x02 - This key may be used to sign data. */
     sign_data: 2,
-    // 0x04 - This key may be used to encrypt communications.
+    /** 0x04 - This key may be used to encrypt communications. */
     encrypt_communication: 4,
-    // 0x08 - This key may be used to encrypt storage.
+    /** 0x08 - This key may be used to encrypt storage. */
     encrypt_storage: 8,
-    // 0x10 - The private component of this key may have been split
-    //        by a secret-sharing mechanism.
+    /** 0x10 - The private component of this key may have been split
+     *        by a secret-sharing mechanism. */
     split_private_key: 16,
-    // 0x20 - This key may be used for authentication.
+    /** 0x20 - This key may be used for authentication. */
     authentication: 32,
-    // 0x80 - The private component of this key may be in the
-    //        possession of more than one person.
+    /** 0x80 - The private component of this key may be in the
+     *        possession of more than one person. */
     shared_private_key: 128
   },
 
   /** Key status
    * @enum {Integer}
+   * @readonly
    */
   keyStatus: {
     invalid:      0,
@@ -301,6 +313,7 @@ module.exports = {
 
   /** Armor type
    * @enum {Integer}
+   * @readonly
    */
   armor: {
     multipart_section: 0,
@@ -339,13 +352,13 @@ module.exports = {
 
 
 
 
 
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/global.html b/doc/global.html deleted file mode 100644 index f44c208b..00000000 --- a/doc/global.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
- -

Global

- - - - - -
- -
-

- -

- -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - -

Members

- -
- -
-

module:util/util

- - -
-
- -
- an instance that should be used. -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- -
- - - - - -

Type Definitions

- -
- -
-

openpgp_block_cipher_fn(block, key) → {openpgp_byte_array}

- - -
-
- - -
- Block cipher function -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
block - - -openpgp_byte_array - - - - A block to perform operations on
key - - -openpgp_byte_array - - - - to use in encryption/decryption
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Encrypted/decrypted block -
- - - -
-
- Type -
-
- -openpgp_byte_array - - -
-
- - - - -
- - - -
-

openpgp_byte_array

- - -
-
- -
- An array of bytes, that is integers with values from 0 to 255 -
- - - -
Type:
-
    -
  • - -Array -| - -Uint8Array - - -
  • -
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- -
- - - -
- -
- - - - -
- - - -
- -
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) -
- - - - - \ No newline at end of file diff --git a/doc/hash.html b/doc/hash.html new file mode 100644 index 00000000..8a51fe04 --- /dev/null +++ b/doc/hash.html @@ -0,0 +1,834 @@ + + + + + JSDoc: Module: crypto/hash + + + + + + + + + + +
+ +

Module: crypto/hash

+ + + + + +
+ +
+

+ crypto/hash +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + +

Requires

+ + + + + + + + + +

Members

+ +
+ +
+

<static> md5

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> ripemd

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sha1

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sha224

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sha256

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sha384

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sha512

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<static> digest(algo, data) → {String}

+ + +
+
+ + +
+ Create a hash on the specified data using the specified algorithm +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +Integer + + + + Hash algorithm type (see RFC4880 9.4)
data + + +String + + + + Data to be hashed
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ hash value +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> getHashByteLength(algo) → {Integer}

+ + +
+
+ + +
+ Returns the hash size in bytes of the specified hash algorithm type +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
algo + + +Integer + + + + Hash algorithm type (See RFC4880 9.4)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ Size in bytes of the resulting hash +
+ + + +
+
+ Type +
+
+ +Integer + + +
+
+ + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/index.html b/doc/index.html index 02a23fea..805791ca 100644 --- a/doc/index.html +++ b/doc/index.html @@ -40,6 +40,48 @@ +
+

[Build Status

+ +

What is OpenPGP.js?

+ +

OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.

+ +

How do I use it?

+ +

As a developer, the best place to start is in the resources/ directory. Within this you will find a basic example implementation and the "binary" files for this library. It is likely that you will want to use resources/openpgp.min.js on your site, this is a minified version of our library.

+ +

I need some help

+ +

Mailing List

+ +

You can sign up for our mailing list and ask for help there. We've recently worked on getting our archive up and running.

+ +

Documentation

+ +

A jsdoc build of our code comments is available at doc/index.html. Public calls should generally be made through the OpenPGP object doc/openpgp.html.

+ +

How do I get involved?

+ +

You want to help, great! Go ahead and fork our repo, make your changes and make a pull request. Please be sure that you run make minify from the root directory to concatenate and minify the library into the resources/ directory.

+ +

It is extra awesome if you write tests for the code you change. Our test coverage is relatively weak, so if you can add cases that is great.

+ +

What License do you use?

+ +

GNU Lesser General Public License (2.1). Please take a look at the LICENSE file for more information.

+ +

What are the requirements to use it?

+ +

OpenPGP.js currently only fully supports Chrome. Firefox support should be coming soon with the advent of Firefox 23 with native javascript support for window.crypto.getRandomValues. If you can help us support more browsers and situations, please chip in!

+ +

Resources

+ +

Below is a collection of resources, many of these were projects that were in someway a precursor to the current OpenPGP.js project. If you'd like to add your link here, please do so in a pull request or email to the list.

+ +
+
+ @@ -51,7 +93,7 @@

- openpgp.js + src/openpgp.js

@@ -133,13 +175,13 @@ for extending and developing on top of the base library.
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/index.js.html b/doc/index.js.html index e09de35b..21667983 100644 --- a/doc/index.js.html +++ b/doc/index.js.html @@ -2,7 +2,7 @@ - JSDoc: Source: crypto/hash/index.js + JSDoc: Source: index.js @@ -17,7 +17,7 @@
-

Source: crypto/hash/index.js

+

Source: index.js

@@ -25,84 +25,45 @@
-
var sha = require('./sha.js');
+            

+module.exports = require('./openpgp.js');
 
-module.exports = {
-  md5: require('./md5.js'),
-  sha1: sha.sha1,
-  sha256: sha.sha256,
-  sha224: sha.sha224,
-  sha384: sha.sha384,
-  sha512: sha.sha512,
-  ripemd: require('./ripe-md.js'),
-
-  /**
-   * Create a hash on the specified data using the specified algorithm
-   * @param {Integer} algo Hash algorithm type (see RFC4880 9.4)
-   * @param {String} data Data to be hashed
-   * @return {String} hash value
-   */
-  digest: function(algo, data) {
-    switch (algo) {
-      case 1:
-        // - MD5 [HAC]
-        return this.md5(data);
-      case 2:
-        // - SHA-1 [FIPS180]
-        return this.sha1(data);
-      case 3:
-        // - RIPE-MD/160 [HAC]
-        return this.ripemd(data);
-      case 8:
-        // - SHA256 [FIPS180]
-        return this.sha256(data);
-      case 9:
-        // - SHA384 [FIPS180]
-        return this.sha384(data);
-      case 10:
-        // - SHA512 [FIPS180]
-        return this.sha512(data);
-      case 11:
-        // - SHA224 [FIPS180]
-        return this.sha224(data);
-      default:
-        throw new Error('Invalid hash function.');
-    }
-  },
-
-  /**
-   * Returns the hash size in bytes of the specified hash algorithm type
-   * @param {Integer} algo Hash algorithm type (See RFC4880 9.4)
-   * @return {Integer} Size in bytes of the resulting hash
-   */
-  getHashByteLength: function(algo) {
-    switch (algo) {
-      case 1:
-        // - MD5 [HAC]
-        return 16;
-      case 2:
-        // - SHA-1 [FIPS180]
-      case 3:
-        // - RIPE-MD/160 [HAC]
-        return 20;
-      case 8:
-        // - SHA256 [FIPS180]
-        return 32;
-      case 9:
-        // - SHA384 [FIPS180]
-        return 48
-      case 10:
-        // - SHA512 [FIPS180]
-        return 64;
-      case 11:
-        // - SHA224 [FIPS180]
-        return 28;
-      default:
-        throw new Error('Invalid hash algorithm.');
-    }
-  }
-
-}
+module.exports.key = require('./key.js');
+module.exports.message = require('./message.js');
+module.exports.cleartext = require('./cleartext.js');
+/**
+ * @see module:util/util
+ * @module util
+ */
+module.exports.util = require('./util/util.js');
+module.exports.packet = require('./packet');
+/**
+ * @see module:type/mpi
+ * @module mpi
+ */
+module.exports.mpi = require('./type/mpi.js');
+/**
+ * @see module:type/s2k
+ * @module s2k
+ */
+module.exports.s2k = require('./type/s2k.js');
+/**
+ * @see module:type/keyid
+ * @module keyid
+ */
+module.exports.keyid = require('./type/keyid.js');
+/**
+ * @see module:encoding/armor
+ * @module armor
+ */
+module.exports.armor = require('./encoding/armor.js');
+module.exports.enums = require('./enums.js');
+/**
+ * @see module:config/config
+ * @module config
+ */
+module.exports.config = require('./config/config.js');
+module.exports.crypto = require('./crypto');
 
@@ -113,13 +74,13 @@ module.exports = {

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/index.js_.html b/doc/index.js_.html new file mode 100644 index 00000000..a024d27f --- /dev/null +++ b/doc/index.js_.html @@ -0,0 +1,76 @@ + + + + + JSDoc: Source: crypto/index.js + + + + + + + + + + +
+ +

Source: crypto/index.js

+ + + + + +
+
+
/**
+ * @see module:crypto/crypto
+ * @module crypto
+ */
+module.exports = {
+  /** @see module:crypto/cipher */
+  cipher: require('./cipher'),
+  /** @see module:crypto/hash */
+  hash: require('./hash'),
+  /** @see module:crypto/cfb */
+  cfb: require('./cfb.js'),
+  /** @see module:crypto/public_key */
+  publicKey: require('./public_key'),
+  /** @see module:crypto/signature */
+  signature: require('./signature.js'),
+  /** @see module:crypto/random */
+  random: require('./random.js'),
+  /** @see module:crypto/pkcs1 */
+  pkcs1: require('./pkcs1.js')
+
+}
+
+var crypto = require('./crypto.js');
+
+for (var i in crypto)
+  module.exports[i] = crypto[i];
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST) +
+ + + + + diff --git a/doc/index.js__.html b/doc/index.js__.html new file mode 100644 index 00000000..cfea5ffb --- /dev/null +++ b/doc/index.js__.html @@ -0,0 +1,78 @@ + + + + + JSDoc: Source: crypto/cipher/index.js + + + + + + + + + + +
+ +

Source: crypto/cipher/index.js

+ + + + + +
+
+
/**
+ * @requires crypto/cipher/aes
+ * @requires crypto/cipher/blowfish
+ * @requires crypto/cipher/cast5
+ * @requires crypto/cipher/twofish
+ * @module crypto/cipher
+ */
+
+var desModule = require('./des.js');
+
+module.exports = {
+  /** @see module:crypto/cipher/des.des */
+  des: desModule['des'],
+  /** @see module:crypto/cipher/des.originalDes */
+  originalDes: desModule['originalDes'],
+  /** @see module:crypto/cipher/cast5 */
+  cast5: require('./cast5.js'),
+  /** @see module:crypto/cipher/twofish */
+  twofish: require('./twofish.js'),
+  /** @see module:crypto/cipher/blowfish */
+  blowfish: require('./blowfish.js')
+}
+
+var aes = require('./aes.js');
+
+for (var i in aes) {
+  module.exports['aes' + i] = aes[i];
+}
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST) +
+ + + + + diff --git a/doc/index.js___.html b/doc/index.js___.html new file mode 100644 index 00000000..9cda7640 --- /dev/null +++ b/doc/index.js___.html @@ -0,0 +1,138 @@ + + + + + JSDoc: Source: crypto/hash/index.js + + + + + + + + + + +
+ +

Source: crypto/hash/index.js

+ + + + + +
+
+
/**
+ * @requires crypto/hash/sha
+ * @module crypto/hash
+ */
+var sha = require('./sha.js');
+
+module.exports = {
+  /** @see module:crypto/hash/md5 */
+  md5: require('./md5.js'),
+  /** @see module:crypto/hash/sha.sha1 */
+  sha1: sha.sha1,
+  /** @see module:crypto/hash/sha.sha224 */
+  sha224: sha.sha224,
+  /** @see module:crypto/hash/sha.sha256 */
+  sha256: sha.sha256,
+  /** @see module:crypto/hash/sha.sha384 */
+  sha384: sha.sha384,
+  /** @see module:crypto/hash/sha.sha512 */
+  sha512: sha.sha512,
+  /** @see module:crypto/hash/ripe-md */
+  ripemd: require('./ripe-md.js'),
+
+  /**
+   * Create a hash on the specified data using the specified algorithm
+   * @param {Integer} algo Hash algorithm type (see RFC4880 9.4)
+   * @param {String} data Data to be hashed
+   * @return {String} hash value
+   */
+  digest: function(algo, data) {
+    switch (algo) {
+      case 1:
+        // - MD5 [HAC]
+        return this.md5(data);
+      case 2:
+        // - SHA-1 [FIPS180]
+        return this.sha1(data);
+      case 3:
+        // - RIPE-MD/160 [HAC]
+        return this.ripemd(data);
+      case 8:
+        // - SHA256 [FIPS180]
+        return this.sha256(data);
+      case 9:
+        // - SHA384 [FIPS180]
+        return this.sha384(data);
+      case 10:
+        // - SHA512 [FIPS180]
+        return this.sha512(data);
+      case 11:
+        // - SHA224 [FIPS180]
+        return this.sha224(data);
+      default:
+        throw new Error('Invalid hash function.');
+    }
+  },
+
+  /**
+   * Returns the hash size in bytes of the specified hash algorithm type
+   * @param {Integer} algo Hash algorithm type (See RFC4880 9.4)
+   * @return {Integer} Size in bytes of the resulting hash
+   */
+  getHashByteLength: function(algo) {
+    switch (algo) {
+      case 1:
+        // - MD5 [HAC]
+        return 16;
+      case 2:
+        // - SHA-1 [FIPS180]
+      case 3:
+        // - RIPE-MD/160 [HAC]
+        return 20;
+      case 8:
+        // - SHA256 [FIPS180]
+        return 32;
+      case 9:
+        // - SHA384 [FIPS180]
+        return 48
+      case 10:
+        // - SHA512 [FIPS180]
+        return 64;
+      case 11:
+        // - SHA224 [FIPS180]
+        return 28;
+      default:
+        throw new Error('Invalid hash algorithm.');
+    }
+  }
+}
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST) +
+ + + + + diff --git a/doc/index.js____.html b/doc/index.js____.html new file mode 100644 index 00000000..0c22b381 --- /dev/null +++ b/doc/index.js____.html @@ -0,0 +1,64 @@ + + + + + JSDoc: Source: crypto/public_key/index.js + + + + + + + + + + +
+ +

Source: crypto/public_key/index.js

+ + + + + +
+
+
/**
+ * @requires crypto/public_key/dsa
+ * @requires crypto/public_key/elgamal
+ * @requires crypto/public_key/rsa
+ * @module crypto/public_key
+ */
+module.exports = {
+  /** @see module:crypto/public_key/rsa */
+  rsa: require('./rsa.js'),
+  /** @see module:crypto/public_key/elgamal */
+  elgamal: require('./elgamal.js'),
+  /** @see module:crypto/public_key/dsa */
+  dsa: require('./dsa.js')
+}
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST) +
+ + + + + diff --git a/doc/jsbn.html b/doc/jsbn.html index 3ad49fab..61b26ed6 100644 --- a/doc/jsbn.html +++ b/doc/jsbn.html @@ -62,7 +62,7 @@
Source:
@@ -83,6 +83,12 @@ +

Requires

+ + + @@ -105,13 +111,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:54 GMT-0800 (PST)
diff --git a/doc/jsbn.js.html b/doc/jsbn.js.html index cf1f4c41..9c817157 100644 --- a/doc/jsbn.js.html +++ b/doc/jsbn.js.html @@ -59,7 +59,10 @@ */ -/** @module crypto/public_key/jsbn */ +/** + * @requires util + * @module crypto/public_key/jsbn + */ var util = require('../../util'); @@ -70,14 +73,14 @@ var dbits; // JavaScript engine analysis var canary = 0xdeadbeefcafe; -var j_lm = ((canary & 0xffffff) == 0xefcafe); +var j_lm = ((canary & 0xffffff) == 0xefcafe); // (public) Constructor function BigInteger(a, b, c) { if (a != null) if ("number" == typeof a) this.fromNumber(a, b, c); - else if (b == null && "string" != typeof a) this.fromString(a, 256); + else if (b == null && "string" != typeof a) this.fromString(a, 256); else this.fromString(a, b); } @@ -100,7 +103,7 @@ function am1(i, x, w, j, c, n) { while (--n >= 0) { var v = x * this[i++] + w[j] + c; c = Math.floor(v / 0x4000000); - w[j++] = v & 0x3ffffff; + w[j++] = v & 0x3ffffff; } return c; } @@ -109,15 +112,15 @@ function am1(i, x, w, j, c, n) { // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) function am2(i, x, w, j, c, n) { - var xl = x & 0x7fff, + var xl = x & 0x7fff, xh = x >> 15; while (--n >= 0) { - var l = this[i] & 0x7fff; + var l = this[i] & 0x7fff; var h = this[i++] >> 15; var m = xh * l + h * xl; - l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); - w[j++] = l & 0x3fffffff; + w[j++] = l & 0x3fffffff; } return c; } @@ -125,24 +128,24 @@ function am2(i, x, w, j, c, n) { // browsers slow down when dealing with 32-bit numbers. function am3(i, x, w, j, c, n) { - var xl = x & 0x3fff, + var xl = x & 0x3fff, xh = x >> 14; while (--n >= 0) { - var l = this[i] & 0x3fff; + var l = this[i] & 0x3fff; var h = this[i++] >> 14; var m = xh * l + h * xl; - l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; c = (l >> 28) + (m >> 14) + xh * h; - w[j++] = l & 0xfffffff; + w[j++] = l & 0xfffffff; } return c; } -/*if(j_lm && (navigator != undefined && +/*if(j_lm && (navigator != undefined && navigator.appName == "Microsoft Internet Explorer")) { BigInteger.prototype.am = am2; dbits = 30; } -else if(j_lm && (navigator != undefined && navigator.appName != "Netscape")) {*/ +else if(j_lm && (navigator != undefined && navigator.appName != "Netscape")) {*/ BigInteger.prototype.am = am1; dbits = 26; /*} @@ -226,7 +229,7 @@ function bnpFromString(s, b) { mi = false, sh = 0; while (--i >= 0) { - var x = (k == 8) ? s[i] & 0xff : intAt(s, i); + var x = (k == 8) ? s[i] & 0xff : intAt(s, i); if (x < 0) { if (s.charAt(i) == "-") mi = true; continue; @@ -235,14 +238,14 @@ function bnpFromString(s, b) { if (sh == 0) this[this.t++] = x; else if (sh + k > this.DB) { - this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; this[this.t++] = (x >> (this.DB - sh)); } else this[this.t - 1] |= x << sh; sh += k; if (sh >= this.DB) sh -= this.DB; } - if (k == 8 && (s[0] & 0x80) != 0) { + if (k == 8 && (s[0] & 0x80) != 0) { this.s = -1; if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; } @@ -253,8 +256,8 @@ function bnpFromString(s, b) { // (protected) clamp off excess high words function bnpClamp() { - var c = this.s & this.DM; - while (this.t > 0 && this[this.t - 1] == c)--this.t; + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c)--this.t; } // (public) return string representation in given radix @@ -274,16 +277,16 @@ function bnToString(b) { i = this.t; var p = this.DB - (i * this.DB) % k; if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } while (i >= 0) { if (p < k) { - d = (this[i] & ((1 << p) - 1)) << (k - p); + d = (this[i] & ((1 << p) - 1)) << (k - p); d |= this[--i] >> (p += this.DB - k); } else { - d = (this[i] >> (p -= k)) & km; + d = (this[i] >> (p -= k)) & km; if (p <= 0) { p += this.DB; --i; @@ -354,7 +357,7 @@ function nbits(x) { function bnBitLength() { if (this.t <= 0) return 0; - return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); } // (protected) r = this << n*DB @@ -382,11 +385,11 @@ function bnpLShiftTo(n, r) { var cbs = this.DB - bs; var bm = (1 << cbs) - 1; var ds = Math.floor(n / this.DB), - c = (this.s << bs) & this.DM, + c = (this.s << bs) & this.DM, i; for (i = this.t - 1; i >= 0; --i) { r[i + ds + 1] = (this[i] >> cbs) | c; - c = (this[i] & bm) << bs; + c = (this[i] & bm) << bs; } for (i = ds - 1; i >= 0; --i) r[i] = 0; r[ds] = c; @@ -409,10 +412,10 @@ function bnpRShiftTo(n, r) { var bm = (1 << bs) - 1; r[0] = this[ds] >> bs; for (var i = ds + 1; i < this.t; ++i) { - r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds - 1] |= (this[i] & bm) << cbs; r[i - ds] = this[i] >> bs; } - if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; r.t = this.t - ds; r.clamp(); } @@ -425,14 +428,14 @@ function bnpSubTo(a, r) { m = Math.min(a.t, this.t); while (i < m) { c += this[i] - a[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } if (a.t < this.t) { c -= a.s; while (i < this.t) { c += this[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c += this.s; @@ -440,7 +443,7 @@ function bnpSubTo(a, r) { c += this.s; while (i < a.t) { c -= a[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c -= a.s; @@ -551,7 +554,7 @@ function bnpDivRemTo(m, q, r) { function bnMod(a) { var r = nbi(); this.abs().divRemTo(a, null, r); - if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); return r; } @@ -604,11 +607,11 @@ Classic.prototype.sqrTo = cSqrTo; function bnpInvDigit() { if (this.t < 1) return 0; var x = this[0]; - if ((x & 1) == 0) return 0; - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 // last step - calculate inverse mod DV directly; // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits @@ -621,7 +624,7 @@ function bnpInvDigit() { function Montgomery(m) { this.m = m; this.mp = m.invDigit(); - this.mpl = this.mp & 0x7fff; + this.mpl = this.mp & 0x7fff; this.mph = this.mp >> 15; this.um = (1 << (m.DB - 15)) - 1; this.mt2 = 2 * m.t; @@ -633,7 +636,7 @@ function montConvert(x) { var r = nbi(); x.abs().dlShiftTo(this.m.t, r); r.divRemTo(this.m, null, r); - if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); return r; } @@ -653,8 +656,8 @@ function montReduce(x) { x[x.t++] = 0; for (var i = 0; i < this.m.t; ++i) { // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i] & 0x7fff; - var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; // use am to combine the multiply-shift-add into one call j = i + this.m.t; x[j] += this.m.am(0, u0, x, i, 0, this.m.t); @@ -692,7 +695,7 @@ Montgomery.prototype.sqrTo = montSqrTo; // (protected) true iff this is even function bnpIsEven() { - return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; + return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; } // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) @@ -706,7 +709,7 @@ function bnpExp(e, z) { g.copyTo(r); while (--i >= 0) { z.sqrTo(r, r2); - if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); else { var t = r; r = r2; @@ -830,7 +833,7 @@ function bnIntValue() { } else if (this.t == 1) return this[0]; else if (this.t == 0) return 0; // assumes 16 < DB < 32 - return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; } // (public) return value as byte @@ -855,7 +858,7 @@ function bnpChunkSize(r) { function bnSigNum() { if (this.s < 0) return -1; - else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; else return 1; } @@ -891,7 +894,7 @@ function bnpFromRadix(s, b) { for (var i = 0; i < s.length; ++i) { var x = intAt(s, i); if (x < 0) { - if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; continue; } w = b * w + x; @@ -928,10 +931,10 @@ function bnpFromNumber(a, b, c) { } else { // new BigInteger(int,RNG) var x = new Array(), - t = a & 7; + t = a & 7; x.length = (a >> 3) + 1; b.nextBytes(x); - if (t > 0) x[0] &= ((1 << t) - 1); + if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0; this.fromString(x, 256); } @@ -946,21 +949,21 @@ function bnToByteArray() { var p = this.DB - (i * this.DB) % 8, d, k = 0; if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | (this.s << (this.DB - p)); while (i >= 0) { if (p < 8) { - d = (this[i] & ((1 << p) - 1)) << (8 - p); + d = (this[i] & ((1 << p) - 1)) << (8 - p); d |= this[--i] >> (p += this.DB - 8); } else { - d = (this[i] >> (p -= 8)) & 0xff; + d = (this[i] >> (p -= 8)) & 0xff; if (p <= 0) { p += this.DB; --i; } } - //if((d&0x80) != 0) d |= -256; - //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + //if((d&0x80) != 0) d |= -256; + //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; if (k > 0 || d != this.s) r[k++] = d; } } @@ -985,11 +988,11 @@ function bnpBitwiseTo(a, op, r) { var i, f, m = Math.min(a.t, this.t); for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); if (a.t < this.t) { - f = a.s & this.DM; + f = a.s & this.DM; for (i = m; i < this.t; ++i) r[i] = op(this[i], f); r.t = this.t; } else { - f = this.s & this.DM; + f = this.s & this.DM; for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); r.t = a.t; } @@ -997,10 +1000,10 @@ function bnpBitwiseTo(a, op, r) { r.clamp(); } -// (public) this & a +// (public) this & a function op_and(x, y) { - return x & y; + return x & y; } function bnAnd(a) { @@ -1033,10 +1036,10 @@ function bnXor(a) { return r; } -// (public) this & ~a +// (public) this & ~a function op_andnot(x, y) { - return x & ~y; + return x & ~y; } function bnAndNot(a) { @@ -1049,7 +1052,7 @@ function bnAndNot(a) { function bnNot() { var r = nbi(); - for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; r.t = this.t; r.s = ~this.s; return r; @@ -1078,23 +1081,23 @@ function bnShiftRight(n) { function lbit(x) { if (x == 0) return -1; var r = 0; - if ((x & 0xffff) == 0) { + if ((x & 0xffff) == 0) { x >>= 16; r += 16; } - if ((x & 0xff) == 0) { + if ((x & 0xff) == 0) { x >>= 8; r += 8; } - if ((x & 0xf) == 0) { + if ((x & 0xf) == 0) { x >>= 4; r += 4; } - if ((x & 3) == 0) { + if ((x & 3) == 0) { x >>= 2; r += 2; } - if ((x & 1) == 0)++r; + if ((x & 1) == 0)++r; return r; } @@ -1112,7 +1115,7 @@ function bnGetLowestSetBit() { function cbit(x) { var r = 0; while (x != 0) { - x &= x - 1; + x &= x - 1; ++r; } return r; @@ -1122,7 +1125,7 @@ function cbit(x) { function bnBitCount() { var r = 0, - x = this.s & this.DM; + x = this.s & this.DM; for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); return r; } @@ -1132,7 +1135,7 @@ function bnBitCount() { function bnTestBit(n) { var j = Math.floor(n / this.DB); if (j >= this.t) return (this.s != 0); - return ((this[j] & (1 << (n % this.DB))) != 0); + return ((this[j] & (1 << (n % this.DB))) != 0); } // (protected) this op (1<<n) @@ -1149,7 +1152,7 @@ function bnSetBit(n) { return this.changeBit(n, op_or); } -// (public) this & ~(1<<n) +// (public) this & ~(1<<n) function bnClearBit(n) { return this.changeBit(n, op_andnot); @@ -1169,14 +1172,14 @@ function bnpAddTo(a, r) { m = Math.min(a.t, this.t); while (i < m) { c += this[i] + a[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } if (a.t < this.t) { c += a.s; while (i < this.t) { c += this[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c += this.s; @@ -1184,7 +1187,7 @@ function bnpAddTo(a, r) { c += this.s; while (i < a.t) { c += a[i]; - r[i++] = c & this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c += a.s; @@ -1431,14 +1434,14 @@ function bnModPow(e, m) { t; i = nbits(e[j]) - 1; while (j >= 0) { - if (i >= k1) w = (e[j] >> (i - k1)) & km; + if (i >= k1) w = (e[j] >> (i - k1)) & km; else { - w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); } n = k; - while ((w & 1) == 0) { + while ((w & 1) == 0) { w >>= 1; --n; } @@ -1464,7 +1467,7 @@ function bnModPow(e, m) { z.mulTo(r2, g[w], r); } - while (j >= 0 && (e[j] & (1 << i)) == 0) { + while (j >= 0 && (e[j] & (1 << i)) == 0) { z.sqrTo(r, r2); t = r; r = r2; @@ -1527,7 +1530,7 @@ function bnpModInt(n) { function bnModInverse(m) { var ac = m.isEven(); - if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; var u = m.clone(), v = this.clone(); var a = nbv(1), @@ -1590,7 +1593,7 @@ var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; function bnIsProbablePrime(t) { var i, x = this.abs(); - if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { for (i = 0; i < lowprimes.length; ++i) if (x[0] == lowprimes[i]) return true; return false; @@ -1600,7 +1603,7 @@ function bnIsProbablePrime(t) { while (i < lowprimes.length) { var m = lowprimes[i], j = i + 1; - while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; m = x.modInt(m); while (i < j) if (m % lowprimes[i++] == 0) return false; } @@ -1639,8 +1642,8 @@ function bnToMPI() { var ba = this.toByteArray(); var size = (ba.length - 1) * 8 + nbits(ba[0]); var result = ""; - result += String.fromCharCode((size & 0xFF00) >> 8); - result += String.fromCharCode(size & 0xFF); + result += String.fromCharCode((size & 0xFF00) >> 8); + result += String.fromCharCode(size & 0xFF); result += util.bin2str(ba); return result; } @@ -1665,9 +1668,9 @@ function bnpMillerRabin(t) { bases.push(j); a.fromInt(j); var y = a.modPow(r, this); - if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { var j = 1; - while (j++ < k && y.compareTo(n1) != 0) { + while (j++ < k && y.compareTo(n1) != 0) { y = y.modPowInt(2, this); if (y.compareTo(BigInteger.ONE) == 0) return false; } @@ -1742,13 +1745,13 @@ BigInteger.prototype.square = bnSquare;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/jxg.js.html b/doc/jxg.js.html index 1ad13b53..4f7a3268 100644 --- a/doc/jxg.js.html +++ b/doc/jxg.js.html @@ -178,11 +178,11 @@ JXG.Util.Unzip = function(barray) { function readBit() { var carry; bits++; - carry = (bb & 1); + carry = (bb & 1); bb >>= 1; if (bb == 0) { bb = readByte(); - carry = (bb & 1); + carry = (bb & 1); bb = (bb >> 1) | 0x80; } return carry; @@ -329,13 +329,13 @@ JXG.Util.Unzip = function(barray) { var tmp; for(tmp=currentTree;tmp<Places;tmp++) { fprintf(stdout, "0x%03x 0x%03x (0x%04x)",tmp-currentTree, tmp->jump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); - if(!(tmp.b0 & 0x8000)) { - //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); + if(!(tmp.b0 & 0x8000)) { + //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); } - if(!(tmp.b1 & 0x8000)) { - if((tmp.b0 & 0x8000)) + if(!(tmp.b1 & 0x8000)) { + if((tmp.b0 & 0x8000)) fprintf(stdout, " "); - fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); + fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); } fprintf(stdout, "\n"); } @@ -355,7 +355,7 @@ JXG.Util.Unzip = function(barray) { if (debug) document.write("b=" + b); if (b) { - if (!(X.b1 & 0x8000)) { + if (!(X.b1 & 0x8000)) { if (debug) document.write("ret1"); return X.b1; /* If leaf node, return data */ @@ -370,7 +370,7 @@ JXG.Util.Unzip = function(barray) { } //xtreepos++; } else { - if (!(X.b0 & 0x8000)) { + if (!(X.b0 & 0x8000)) { if (debug) document.write("ret2"); return X.b0; /* If leaf node, return data */ @@ -427,7 +427,7 @@ JXG.Util.Unzip = function(barray) { cSum = readByte(); cSum |= (readByte() << 8); - if (((blockLen ^ ~cSum) & 0xffff)) { + if (((blockLen ^ ~cSum) & 0xffff)) { document.write("BlockLen checksum mismatch\n"); } while (blockLen--) { @@ -497,7 +497,7 @@ JXG.Util.Unzip = function(barray) { /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ for (j = 0; j < len; j++) { - var c = buf32k[(bIdx - dist) & 0x7fff]; + var c = buf32k[(bIdx - dist) & 0x7fff]; addBuffer(c); } } @@ -585,7 +585,7 @@ JXG.Util.Unzip = function(barray) { } /*for(j=0; j<literalCodes+distCodes; j++) { //fprintf(errfp, "%d ", ll[j]); - if ((j&7)==7) + if ((j&7)==7) fprintf(errfp, "\n"); } fprintf(errfp, "\n");*/ @@ -634,7 +634,7 @@ JXG.Util.Unzip = function(barray) { if (bIdx - dist < 0) { break outer; } - var c = buf32k[(bIdx - dist) & 0x7fff]; + var c = buf32k[(bIdx - dist) & 0x7fff]; addBuffer(c); } } else { @@ -710,7 +710,7 @@ JXG.Util.Unzip = function(barray) { tmp[1] = readByte(); if (debug) alert("type: " + tmp[0] + " " + tmp[1]); - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("da", 16)) { //GZIP + if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("da", 16)) { //GZIP if (debug) alert("GEONExT-GZIP"); DeflateLoop(); @@ -721,7 +721,7 @@ JXG.Util.Unzip = function(barray) { unzipped[files][1] = "geonext.gxt"; files++; } - if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("9c", 16)) { //ZLIB + if (tmp[0] == parseInt("78", 16) && tmp[1] == parseInt("9c", 16)) { //ZLIB if (debug) alert("ZLIB"); DeflateLoop(); @@ -732,7 +732,7 @@ JXG.Util.Unzip = function(barray) { unzipped[files][1] = "ZLIB"; files++; } - if (tmp[0] == parseInt("1f", 16) && tmp[1] == parseInt("8b", 16)) { //GZIP + if (tmp[0] == parseInt("1f", 16) && tmp[1] == parseInt("8b", 16)) { //GZIP if (debug) alert("GZIP"); //DeflateLoop(); @@ -744,11 +744,11 @@ JXG.Util.Unzip = function(barray) { unzipped[files][1] = "file"; files++; } - if (tmp[0] == parseInt("50", 16) && tmp[1] == parseInt("4b", 16)) { //ZIP + if (tmp[0] == parseInt("50", 16) && tmp[1] == parseInt("4b", 16)) { //ZIP modeZIP = true; tmp[2] = readByte(); tmp[3] = readByte(); - if (tmp[2] == parseInt("3", 16) && tmp[3] == parseInt("4", 16)) { + if (tmp[2] == parseInt("3", 16) && tmp[3] == parseInt("4", 16)) { //MODE_ZIP tmp[0] = readByte(); tmp[1] = readByte(); @@ -821,7 +821,7 @@ JXG.Util.Unzip = function(barray) { CRC = 0xffffffff; SIZE = 0; - if (size == 0 && fileOut.charAt(fileout.length - 1) == "/") { + if (size == 0 && fileOut.charAt(fileout.length - 1) == "/") { //skipdir if (debug) alert("skipdir"); @@ -846,15 +846,15 @@ JXG.Util.Unzip = function(barray) { tmp = [], compSize, size, os, i, c; - if ((gpflags & 8)) { + if ((gpflags & 8)) { tmp[0] = readByte(); tmp[1] = readByte(); tmp[2] = readByte(); tmp[3] = readByte(); - if (tmp[0] == parseInt("50", 16) && - tmp[1] == parseInt("4b", 16) && - tmp[2] == parseInt("07", 16) && + if (tmp[0] == parseInt("50", 16) && + tmp[1] == parseInt("4b", 16) && + tmp[2] == parseInt("07", 16) && tmp[3] == parseInt("08", 16)) { crc = readByte(); crc |= (readByte() << 8); @@ -890,7 +890,7 @@ JXG.Util.Unzip = function(barray) { gpflags = readByte(); if (debug) { - if ((gpflags & ~(parseInt("1f", 16)))) + if ((gpflags & ~(parseInt("1f", 16)))) alert("Unknown flags set!"); } @@ -902,7 +902,7 @@ JXG.Util.Unzip = function(barray) { readByte(); os = readByte(); - if ((gpflags & 4)) { + if ((gpflags & 4)) { tmp[0] = readByte(); tmp[2] = readByte(); len = tmp[0] + 256 * tmp[1]; @@ -912,7 +912,7 @@ JXG.Util.Unzip = function(barray) { readByte(); } - if ((gpflags & 8)) { + if ((gpflags & 8)) { i = 0; nameBuf = []; while (c = readByte()) { @@ -926,13 +926,13 @@ JXG.Util.Unzip = function(barray) { alert("original file name: " + nameBuf); } - if ((gpflags & 16)) { + if ((gpflags & 16)) { while (c = readByte()) { //FILE COMMENT } } - if ((gpflags & 2)) { + if ((gpflags & 2)) { readByte(); readByte(); } @@ -980,9 +980,9 @@ JXG.Util.Base64 = { chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; @@ -1017,8 +1017,8 @@ JXG.Util.Base64 = { enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; output.push(String.fromCharCode(chr1)); @@ -1050,13 +1050,13 @@ JXG.Util.Base64 = { if (c < 128) { utftext += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { + } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); } } @@ -1077,14 +1077,14 @@ JXG.Util.Base64 = { if (c < 128) { string.push(String.fromCharCode(c)); i++; - } else if ((c > 191) && (c < 224)) { + } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); i += 3; } } @@ -1241,14 +1241,14 @@ JXG.Util.utf8Decode = function(utftext) { if (c < 128) { string.push(String.fromCharCode(c)); i++; - } else if ((c > 191) && (c < 224)) { + } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); i += 3; } }; @@ -1281,9 +1281,9 @@ JXG.Util.genUUID = function() { uuid[i] = '4'; } else { if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0; - r = rnd & 0xf; + r = rnd & 0xf; rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } } @@ -1302,13 +1302,13 @@ module.exports = JXG;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/key.js.html b/doc/key.js.html index 5bdae82e..336bafa9 100644 --- a/doc/key.js.html +++ b/doc/key.js.html @@ -42,12 +42,18 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module key */ +/** + * @requires config + * @requires encoding/armor + * @requires enums + * @requires packet + * @module key + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'); /** * @class @@ -317,7 +323,7 @@ Key.prototype.getSigningKeyPacket = function() { throw new Error('Need private key for signing'); } var primaryUser = this.getPrimaryUser(); - if (primaryUser && + if (primaryUser && isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate)) { return this.primaryKey; } @@ -337,25 +343,25 @@ Key.prototype.getSigningKeyPacket = function() { */ Key.prototype.getPreferredHashAlgorithm = function() { var primaryUser = this.getPrimaryUser(); - if (primaryUser && primaryUser.selfCertificate.preferredHashAlgorithms) { + if (primaryUser && primaryUser.selfCertificate.preferredHashAlgorithms) { return primaryUser.selfCertificate.preferredHashAlgorithms[0]; } return config.prefer_hash_algorithm; }; function isValidEncryptionKeyPacket(keyPacket, signature) { - return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.dsa) && - keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_sign) && - ((signature.keyFlags & enums.keyFlags.encrypt_communication) !== 0 || - (signature.keyFlags & enums.keyFlags.encrypt_storage) !== 0 || + return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.dsa) && + keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_sign) && + ((signature.keyFlags & enums.keyFlags.encrypt_communication) !== 0 || + (signature.keyFlags & enums.keyFlags.encrypt_storage) !== 0 || !signature.keyFlags); }; function isValidSigningKeyPacket(keyPacket, signature) { return (keyPacket.algorithm == enums.read(enums.publicKey, enums.publicKey.dsa) || keyPacket.algorithm == enums.read(enums.publicKey, enums.publicKey.rsa_sign) || - keyPacket.algorithm == enums.read(enums.publicKey, enums.publicKey.rsa_encrypt_sign)) && - ((signature.keyFlags & enums.keyFlags.sign_data) !== 0 || + keyPacket.algorithm == enums.read(enums.publicKey, enums.publicKey.rsa_encrypt_sign)) && + ((signature.keyFlags & enums.keyFlags.sign_data) !== 0 || !signature.keyFlags); }; @@ -375,7 +381,7 @@ Key.prototype.getEncryptionKeyPacket = function() { } // if no valid subkey for encryption, evaluate primary key var primaryUser = this.getPrimaryUser(); - if (primaryUser && + if (primaryUser && isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate)) { return this.primaryKey; } @@ -431,13 +437,13 @@ Key.prototype.decryptKeyPacket = function(keyIds, passphrase) { */ Key.prototype.verifyPrimaryKey = function() { // check revocation signature - if (this.revocationSignature && !this.revocationSignature.isExpired() && + if (this.revocationSignature && !this.revocationSignature.isExpired() && (this.revocationSignature.verified || this.revocationSignature.verify(this.primaryKey, {key: this.primaryKey}))) { return enums.keyStatus.revoked; } // check V3 expiration time - if (this.primaryKey.version == 3 && this.primaryKey.expirationTimeV3 !== 0 && + if (this.primaryKey.version == 3 && this.primaryKey.expirationTimeV3 !== 0 && Date.now() > (this.primaryKey.created.getTime() + this.primaryKey.expirationTimeV3*24*3600*1000)) { return enums.keyStatus.expired; } @@ -445,7 +451,7 @@ Key.prototype.verifyPrimaryKey = function() { // See http://tools.ietf.org/html/rfc4880#section-11.1 var selfSigned = false; for (var i = 0; i < this.users.length; i++) { - if (this.users[i].userId && this.users[i].selfCertifications) { + if (this.users[i].userId && this.users[i].selfCertifications) { selfSigned = true; } } @@ -458,7 +464,7 @@ Key.prototype.verifyPrimaryKey = function() { return enums.keyStatus.invalid; } // check V4 expiration time - if (this.primaryKey.version == 4 && primaryUser.selfCertificate.keyNeverExpires === false && + if (this.primaryKey.version == 4 && primaryUser.selfCertificate.keyNeverExpires === false && Date.now() > (primaryUser.selfCertificate.created.getTime() + primaryUser.selfCertificate.keyExpirationTime*1000)) { return enums.keyStatus.expired; } @@ -483,7 +489,7 @@ Key.prototype.getPrimaryUser = function() { continue; } if (!user || - !userSelfCert.isPrimaryUserID && selfCert.isPrimaryUserID || + !userSelfCert.isPrimaryUserID && selfCert.isPrimaryUserID || userSelfCert.created < selfCert.created) { user = this.users[i]; userSelfCert = selfCert; @@ -535,8 +541,8 @@ User.prototype.isRevoked = function(certificate, primaryKey) { if (this.revocationCertifications) { var that = this; return this.revocationCertifications.some(function(revCert) { - return revCert.issuerKeyId.equals(certificate.issuerKeyId) && - !revCert.isExpired() && + return revCert.issuerKeyId.equals(certificate.issuerKeyId) && + !revCert.isExpired() && (revCert.verified || revCert.verify(primaryKey, {userid: that.userId || that.userAttribute, key: primaryKey})); }); @@ -559,7 +565,7 @@ User.prototype.getValidSelfCertificate = function(primaryKey) { if (this.isRevoked(this.selfCertifications[i], primaryKey)) { continue; } - if (!this.selfCertifications[i].isExpired() && + if (!this.selfCertifications[i].isExpired() && (this.selfCertifications[i].verified || this.selfCertifications[i].verify(primaryKey, {userid: this.userId || this.userAttribute, key: primaryKey}))) { validCert.push(this.selfCertifications[i]); @@ -636,7 +642,7 @@ SubKey.prototype.toPacketlist = function() { * @return {Boolean} */ SubKey.prototype.isValidEncryptionKey = function(primaryKey) { - return this.verify(primaryKey) == enums.keyStatus.valid && + return this.verify(primaryKey) == enums.keyStatus.valid && isValidEncryptionKeyPacket(this.subKey, this.bindingSignature); }; @@ -646,7 +652,7 @@ SubKey.prototype.isValidEncryptionKey = function(primaryKey) { * @return {Boolean} */ SubKey.prototype.isValidSigningKey = function(primaryKey) { - return this.verify(primaryKey) == enums.keyStatus.valid && + return this.verify(primaryKey) == enums.keyStatus.valid && isValidSigningKeyPacket(this.subKey, this.bindingSignature); }; @@ -657,13 +663,13 @@ SubKey.prototype.isValidSigningKey = function(primaryKey) { */ SubKey.prototype.verify = function(primaryKey) { // check subkey revocation signature - if (this.revocationSignature && !this.revocationSignature.isExpired() && + if (this.revocationSignature && !this.revocationSignature.isExpired() && (this.revocationSignature.verified || this.revocationSignature.verify(primaryKey, {key: this.subKey}))) { return enums.keyStatus.revoked; } // check V3 expiration time - if (this.subKey.version == 3 && this.subKey.expirationTimeV3 !== 0 && + if (this.subKey.version == 3 && this.subKey.expirationTimeV3 !== 0 && Date.now() > (this.subKey.created.getTime() + this.subKey.expirationTimeV3*24*3600*1000)) { return enums.keyStatus.expired; } @@ -679,8 +685,8 @@ SubKey.prototype.verify = function(primaryKey) { return enums.keyStatus.invalid; } // check V4 expiration time - if (this.subKey.version == 4 && - this.bindingSignature.keyNeverExpires === false && + if (this.subKey.version == 4 && + this.bindingSignature.keyNeverExpires === false && Date.now() > (this.subKey.created.getTime() + this.bindingSignature.keyExpirationTime*1000)) { return enums.keyStatus.expired; } @@ -691,6 +697,7 @@ SubKey.prototype.verify = function(primaryKey) { * Reads an OpenPGP armored text and returns one or multiple key objects * @param {String} armoredText text to be parsed * @return {{keys: Array<module:key~Key>, err: (Array<Error>|null)}} result object with key and error arrays + * @static */ function readArmored(armoredText) { var result = {}; @@ -732,6 +739,7 @@ function readArmored(armoredText) { * @param {String} userId assumes already in form of "User Name <username@email.com>" * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {module:key~Key} + * @static */ function generate(keyType, numBits, userId, passphrase) { var packetlist = new packet.list(); @@ -793,13 +801,13 @@ exports.generate = generate;
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/keyid.html b/doc/keyid.html index b92ca530..49762552 100644 --- a/doc/keyid.html +++ b/doc/keyid.html @@ -36,8 +36,16 @@
+
Implementation of type key id (RFC4880 3.3)
+
+A Key ID is an eight-octet scalar that identifies a key. +Implementations SHOULD NOT assume that Key IDs are unique. The +section "Enhanced Key Formats" below describes how Key IDs are +formed.
+ +
-

new require("type/keyid")()

+

new (require("type/keyid"))()

@@ -74,7 +82,7 @@
Source:
@@ -148,6 +156,12 @@ +

Requires

+ + + @@ -161,7 +175,7 @@
-

read(input, position) → {module:type/keyid}

+

read(input)

@@ -223,30 +237,6 @@ - - - - position - - - - - -integer - - - - - - - - - - Position where to start reading the key -id from input - - - @@ -274,7 +264,7 @@ id from input
Source:
@@ -295,28 +285,6 @@ id from input -
Returns:
- - -
- This object -
- - - -
-
- Type -
-
- -module:type/keyid - - -
-
- - @@ -337,13 +305,13 @@ id from input

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST)
diff --git a/doc/keyid.js.html b/doc/keyid.js.html index f5344d76..a11e9ee4 100644 --- a/doc/keyid.js.html +++ b/doc/keyid.js.html @@ -42,19 +42,23 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module type/keyid */ +/** + * Implementation of type key id (RFC4880 3.3)<br/> + * <br/> + * A Key ID is an eight-octet scalar that identifies a key. + * Implementations SHOULD NOT assume that Key IDs are unique. The + * section "Enhanced Key Formats" below describes how Key IDs are + * formed. + * @requires util + * @module type/keyid + */ var util = require('../util'); /** - * @class - * @classdesc Implementation of type key id (RFC4880 3.3) - * A Key ID is an eight-octet scalar that identifies a key. - Implementations SHOULD NOT assume that Key IDs are unique. The - section "Enhanced Key Formats" below describes how Key IDs are - formed. + * @constructor */ -module.exports = function keyid() { +module.exports = function () { this.bytes = ''; @@ -62,30 +66,27 @@ module.exports = function keyid() { /** * Parsing method for a key id * @param {String} input Input to read the key id from - * @param {integer} position Position where to start reading the key - * id from input - * @return {module:type/keyid} This object */ this.read = function(bytes) { this.bytes = bytes.substr(0, 8); - } + }; this.write = function() { return this.bytes; - } + }; this.toHex = function() { return util.hexstrdump(this.bytes); - } + }; this.equals = function(keyid) { return this.bytes == keyid.bytes; - } + }; this.isNull = function() { return this.bytes === ''; - } -} + }; +}; module.exports.mapToHex = function(keyId) { return keyId.toHex(); @@ -100,13 +101,13 @@ module.exports.mapToHex = function(keyId) {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/keyring.html b/doc/keyring.html index 9e3db82b..9cbff110 100644 --- a/doc/keyring.html +++ b/doc/keyring.html @@ -36,20 +36,88 @@
+
The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
+ +
-

new require("keyring/keyring")()

+

new (require("keyring/keyring"))(storeHandler)

+
+ Initialization routine for the keyring. This method reads the +keyring from HTML5 local storage and initializes this instance. +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeArgumentDescription
storeHandler + + +class + + + + + + <optional>
+ + + + + +
class implementing load() and store() methods
+
@@ -74,7 +142,7 @@
Source:
@@ -148,6 +216,12 @@ +

Requires

+ + + @@ -160,6 +234,631 @@
+
+

clear()

+ + +
+
+ + +
+ Clear the keyring - erase all the keys +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

exportKey(index) → {String}

+ + +
+
+ + +
+ returns the armored message representation of the key at key ring index +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
index + + +Integer + + + + the index of the key within the array
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ armored message representing the key object +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

exportPublicKey(index) → {String}

+ + +
+
+ + +
+ returns the armored message representation of the public key portion of the key at key ring index +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
index + + +Integer + + + + the index of the key within the array
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ armored message representing the public key object +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

getKeysForKeyId(keyId) → {Array.<module:key~Key>}

+ + +
+
+ + +
+ Searches the keyring for public keys having the specified key id +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keyId + + +String + + + + provided as string of hex number (lowercase)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ public keys found +
+ + + +
+
+ Type +
+
+ +Array.<module:key~Key> + + +
+
+ + + + +
+ + + +
+

getPrivateKeyForAddress(email) → {Array.<module:key~Key>}

+ + +
+
+ + +
+ Searches the keyring for a private key containing the specified email address +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
email + + +String + + + + email address to search for
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ private keys found +
+ + + +
+
+ Type +
+
+ +Array.<module:key~Key> + + +
+
+ + + + +
+ + +

getPublicKeyForAddress(email) → {Array.<module:key~Key>}

@@ -250,7 +949,7 @@
Source:
@@ -300,634 +999,7 @@
-

init()

- - -
-
- - -
- Initialization routine for the keyring. This method reads the -keyring from HTML5 local storage and initializes this instance. -This method is called by openpgp.init(). -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

<inner> exportKey(index) → {String}

- - -
-
- - -
- returns the armored message representation of the key at key ring index -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
index - - -Integer - - - - the index of the key within the array
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- armored message representing the key object -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

<inner> exportPublicKey(index) → {String}

- - -
-
- - -
- returns the armored message representation of the public key portion of the key at key ring index -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
index - - -Integer - - - - the index of the key within the array
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- armored message representing the public key object -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

<inner> getKeysForKeyId(keyId) → {Array.<module:key~Key>}

- - -
-
- - -
- Searches the keyring for public keys having the specified key id -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
keyId - - -String - - - - provided as string of hex number (lowercase)
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- public keys found -
- - - -
-
- Type -
-
- -Array.<module:key~Key> - - -
-
- - - - -
- - - -
-

<inner> getPrivateKeyForAddress(email) → {Array.<module:key~Key>}

- - -
-
- - -
- Searches the keyring for a private key containing the specified email address -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
email - - -String - - - - email address to search for
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- private keys found -
- - - -
-
- Type -
-
- -Array.<module:key~Key> - - -
-
- - - - -
- - - -
-

<inner> importKey(armored)

+

importKey(armored)

@@ -1016,7 +1088,7 @@ This method is called by openpgp.init().
Source:
@@ -1044,7 +1116,7 @@ This method is called by openpgp.init().
-

<inner> removeKey(index) → {module:key~Key}

+

removeKey(index) → {module:key~Key}

@@ -1133,7 +1205,7 @@ This method is called by openpgp.init().
Source:
@@ -1178,12 +1250,779 @@ This method is called by openpgp.init(). +
+ + + +
+

store()

+ + +
+
+ + +
+ Calls the storeHandler to save the keys +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<inner> checkForIdentityAndKeyTypeMatch(keys, identityFunction, identityInput, keyType) → {Array.<module:key~Key>}

+ + +
+
+ + +
+ searches all public keys in the keyring matching the address or address part of the user ids +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keys + + +Array.<module:key~Key> + + + + array of keys to search
identityFunction + + +module:keyring/keyring.checkCallback + + + + callback function which checks for a match
identityInput + + +String + + + + input to check against
keyType + + +module:enums.packet + + + + packet types of keys to check
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ array of keys which match +
+ + + +
+
+ Type +
+
+ +Array.<module:key~Key> + + +
+
+ + + + +
+ + + +
+

<inner> emailCheck(email, key) → {Boolean}

+ + +
+
+ + +
+ Checks a key to see if it matches the specified email address +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
email + + +String + + + + email address to search for
key + + +module:key~Key + + + + The key to be checked.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ True if the email address is defined in the specified key +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + +
+ + + +
+

<inner> idCheck(id, key) → {Boolean}

+ + +
+
+ + +
+ Checks a key to see if it matches the specified keyid +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
id + + +String + + + + hex string keyid to search for
key + + +module:key~Key + + + + the key to be checked.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ true if the email address is defined in the specified key +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + +
+

Type Definitions

+ +
+ +
+

checkCallback(input, key) → {Boolean}

+ + +
+
+ + +
+ Callback to check if a key matches the input +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
input + + +String + + + + input to search for
key + + +module:key~Key + + + + The key to be checked.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ True if the input matches the specified key +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + +
+ +
+ @@ -1196,13 +2035,13 @@ This method is called by openpgp.init().
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/keyring.js.html b/doc/keyring.js.html index bf4019f4..4979f779 100644 --- a/doc/keyring.js.html +++ b/doc/keyring.js.html @@ -42,36 +42,55 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/keyring */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/keyring + */ var openpgp = require('openpgp'); /** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * Callback to check if a key matches the input + * @callback module:keyring/keyring.checkCallback + * @param {String} input input to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the input matches the specified key */ -module.exports = function() { - this.keys = []; + +/** + * Initialization routine for the keyring. This method reads the + * keyring from HTML5 local storage and initializes this instance. + * @constructor + * @param {class} [storeHandler] class implementing load() and store() methods + */ +module.exports = function(storeHandler) { + if (!storeHandler) { + storeHandler = new (require('./localstore.js'))(); + } + this.storeHandler = storeHandler; + this.keys = this.storeHandler.load(); /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Calls the storeHandler to save the keys */ - this.init = function (storeHandler) { - if (!storeHandler) { - var localstore = require('./localstore.js'); - storeHandler = new localstore(); - } - this.storeHandler = storeHandler; - this.keys = []; - this.storeHandler.init(this.keys); - } - this.store = function () { this.storeHandler.store(this.keys); - } + }; + /** + * Clear the keyring - erase all the keys + */ + this.clear = function() { + this.keys = []; + }; + + /** + * Checks a key to see if it matches the specified email address + * @param {String} email email address to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the email address is defined in the specified key + */ function emailCheck(email, key) { email = email.toLowerCase(); var keyEmails = key.getUserIds(); @@ -85,6 +104,13 @@ module.exports = function() { return false; } + /** + * Checks a key to see if it matches the specified keyid + * @param {String} id hex string keyid to search for + * @param {module:key~Key} key the key to be checked. + * @return {Boolean} true if the email address is defined in the specified key + * @inner + */ function idCheck(id, key) { var keyids = key.getKeyIds(); for (var i = 0; i < keyids.length; i++) { @@ -95,18 +121,26 @@ module.exports = function() { return false; } + /** + * searches all public keys in the keyring matching the address or address part of the user ids + * @param {Array<module:key~Key>} keys array of keys to search + * @param {module:keyring/keyring.checkCallback} identityFunction callback function which checks for a match + * @param {String} identityInput input to check against + * @param {module:enums.packet} keyType packet types of keys to check + * @return {Array<module:key~Key>} array of keys which match + */ function checkForIdentityAndKeyTypeMatch(keys, identityFunction, identityInput, keyType) { var results = []; for (var p = 0; p < keys.length; p++) { var key = keys[p]; switch (keyType) { case openpgp.enums.packet.public_key: - if (key.isPublic() && identityFunction(identityInput, key)) { + if (key.isPublic() && identityFunction(identityInput, key)) { results.push(key); } break; case openpgp.enums.packet.private_key: - if (key.isPrivate() && identityFunction(identityInput, key)) { + if (key.isPrivate() && identityFunction(identityInput, key)) { results.push(key); } break; @@ -114,7 +148,6 @@ module.exports = function() { } return results; } - this.checkForIdentityAndKeyTypeMatch = checkForIdentityAndKeyTypeMatch; /** * searches all public keys in the keyring matching the address or address part of the user ids @@ -123,71 +156,64 @@ module.exports = function() { */ this.getPublicKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.public_key); - } + }; /** * Searches the keyring for a private key containing the specified email address * @param {String} email email address to search for * @return {Array<module:key~Key>} private keys found */ - function getPrivateKeyForAddress(email) { + this.getPrivateKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.secret_key); - } - this.getPrivateKeyForAddress = getPrivateKeyForAddress; + }; /** * Searches the keyring for public keys having the specified key id * @param {String} keyId provided as string of hex number (lowercase) * @return {Array<module:key~Key>} public keys found */ - function getKeysForKeyId(keyId) { - return this.checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); - } - this.getKeysForKeyId = getKeysForKeyId; + this.getKeysForKeyId = function (keyId) { + return checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); + }; /** * Imports a key from an ascii armored message * @param {String} armored message to read the keys/key from */ - function importKey(armored) { + this.importKey = function (armored) { this.keys = this.keys.concat(openpgp.key.readArmored(armored).keys); return true; - } - this.importKey = importKey; + }; /** * returns the armored message representation of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the key object */ - function exportKey(index) { + this.exportKey = function (index) { return this.keys[index].armor(); - } - this.exportKey = exportKey; + }; /** - * Removes a public key from the public key keyring at the specified index + * Removes a public key from the public key keyring at the specified index * @param {Integer} index the index of the public key within the publicKeys array * @return {module:key~Key} The public key object which has been removed */ - function removeKey(index) { + this.removeKey = function (index) { var removed = this.keys.splice(index, 1); return removed; - } - this.removeKey = removeKey; + }; /** * returns the armored message representation of the public key portion of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the public key object */ - function exportPublicKey(index) { + this.exportPublicKey = function (index) { return this.keys[index].toPublic().armor(); - } - this.exportPublicKey = exportPublicKey; - + }; };
@@ -199,13 +225,13 @@ module.exports = function() {
diff --git a/doc/literal.html b/doc/literal.html index 83f13043..7dd06758 100644 --- a/doc/literal.html +++ b/doc/literal.html @@ -36,8 +36,14 @@
+
Implementation of the Literal Data Packet (Tag 11)
+
+RFC4880 5.9: A Literal Data packet contains the body of a message; data that +is not to be further interpreted.
+ +
-

new require("packet/literal")()

+

new (require("packet/literal"))()

@@ -74,7 +80,7 @@
Source:
@@ -148,6 +154,14 @@ +

Requires

+ + + @@ -202,7 +216,7 @@
Source:
@@ -294,7 +308,7 @@ with normalized end of line to \n
Source:
@@ -480,7 +494,7 @@ with normalized end of line to \n
Source:
@@ -648,7 +662,7 @@ with normalized end of line to \n
Source:
@@ -766,7 +780,7 @@ will be normalized to \r\n and by default text is converted to UTF8
Source:
@@ -883,7 +897,7 @@ will be normalized to \r\n and by default text is converted to UTF8
Source:
@@ -946,13 +960,13 @@ will be normalized to \r\n and by default text is converted to UTF8

diff --git a/doc/literal.js.html b/doc/literal.js.html index 545dbf66..8819d053 100644 --- a/doc/literal.js.html +++ b/doc/literal.js.html @@ -42,19 +42,23 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/literal */ +/** + * Implementation of the Literal Data Packet (Tag 11)<br/> + * <br/> + * RFC4880 5.9: A Literal Data packet contains the body of a message; data that + * is not to be further interpreted. + * @requires enums + * @requires util + * @module packet/literal + */ var util = require('../util'), enums = require('../enums.js'); /** - * @class - * @classdesc Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. + * @constructor */ -module.exports = function packet_literal() { +module.exports = function () { this.format = 'utf8'; // default format for literal data packets this.data = ''; // literal data representation as native JavaScript string or bytes this.date = new Date(); @@ -160,13 +164,13 @@ module.exports = function packet_literal() {
diff --git a/doc/localStorage.html b/doc/localStorage.html new file mode 100644 index 00000000..5ef99a0c --- /dev/null +++ b/doc/localStorage.html @@ -0,0 +1,332 @@ + + + + + JSDoc: Module: config/localStorage + + + + + + + + + + +
+ +

Module: config/localStorage

+ + + + + +
+ +
+

+ config/localStorage +

+ +
+ +
+
+ + +
This object storing and retrieving configuration from HTML5 local storage.
+ + +
+

new (require("config/localStorage"))()

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + +

Methods

+ +
+ +
+

read()

+ + +
+
+ + +
+ Reads the config out of the HTML5 local storage +and initializes the object config. +if config is null the default config will be used +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

write()

+ + +
+
+ + +
+ Writes the config to HTML5 local storage +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/doc/localStorage.js.html b/doc/localStorage.js.html new file mode 100644 index 00000000..92239422 --- /dev/null +++ b/doc/localStorage.js.html @@ -0,0 +1,81 @@ + + + + + JSDoc: Source: config/localStorage.js + + + + + + + + + + +
+ +

Source: config/localStorage.js

+ + + + + +
+
+
/**
+ * This object storing and retrieving configuration from HTML5 local storage.
+ * @module config/localStorage
+ */
+
+/**
+ * @constructor
+ */
+module.exports = function () {
+
+  /**
+   * Reads the config out of the HTML5 local storage
+   * and initializes the object config.
+   * if config is null the default config will be used
+   */
+  this.read = function () {
+    var cf = JSON.parse(window.localStorage.getItem("config"));
+    if (cf === null) {
+      this.config = this.default_config;
+      this.write();
+    } else
+      this.config = cf;
+  }
+
+  /**
+   * Writes the config to HTML5 local storage
+   */
+  this.write = function () {
+    window.localStorage.setItem("config", JSON.stringify(this.config));
+  }
+}
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/doc/localstore.html b/doc/localstore.html index 09f19cd5..4163ad35 100644 --- a/doc/localstore.html +++ b/doc/localstore.html @@ -35,73 +35,10 @@
- -
-

new require("keyring/localstore")()

-
-
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - - +
The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
@@ -148,6 +85,12 @@ +

Requires

+ + + @@ -161,7 +104,7 @@
-

init()

+

<static> load() → {Array.<module:key~Key>}

@@ -169,9 +112,7 @@
- Initialization routine for the keyring. This method reads the -keyring from HTML5 local storage and initializes this instance. -This method is called by openpgp.init(). + Load the keyring from HTML5 local storage and initializes this instance.
@@ -204,7 +145,7 @@ This method is called by openpgp.init().
Source:
@@ -225,6 +166,28 @@ This method is called by openpgp.init(). +
Returns:
+ + +
+ array of keys retrieved from localstore +
+ + + +
+
+ Type +
+
+ +Array.<module:key~Key> + + +
+
+ + @@ -232,7 +195,7 @@ This method is called by openpgp.init().
-

store()

+

<static> store(keys)

@@ -250,6 +213,54 @@ The privateKeys array and publicKeys array gets Stringified using JSON +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
keys + + +Array.<module:key~Key> + + + + array of keys to save in localstore
+
@@ -315,13 +326,13 @@ The privateKeys array and publicKeys array gets Stringified using JSON

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/localstore.js.html b/doc/localstore.js.html index 4317deb6..554dfd54 100644 --- a/doc/localstore.js.html +++ b/doc/localstore.js.html @@ -42,36 +42,36 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/localstore */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/localstore + */ var openpgp = require('openpgp'); -/** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. - */ module.exports = function () { /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Load the keyring from HTML5 local storage and initializes this instance. + * @return {Array<module:key~Key>} array of keys retrieved from localstore */ - this.init = function (keys) { + this.load = function () { var armoredKeys = JSON.parse(window.localStorage.getItem("armoredKeys")); - if (armoredKeys !== null && armoredKeys.length === 0) { + var keys = []; + if (armoredKeys !== null && armoredKeys.length !== 0) { var key; for (var i = 0; i < armoredKeys.length; i++) { key = openpgp.key.readArmored(armoredKeys[i]); keys.push(key); } - } else { - this.keys = []; } + return keys; } /** * Saves the current state of the keyring to HTML5 local storage. * The privateKeys array and publicKeys array gets Stringified using JSON + * @param {Array<module:key~Key>} keys array of keys to save in localstore */ this.store = function (keys) { var armoredKeys = []; @@ -91,13 +91,13 @@ module.exports = function () {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/marker.html b/doc/marker.html index af2d684a..3cbb6d14 100644 --- a/doc/marker.html +++ b/doc/marker.html @@ -36,8 +36,18 @@
+
Implementation of the strange "Marker packet" (Tag 10)
+
+RFC4880 5.8: An experimental version of PGP used this packet as the Literal +packet, but no released version of PGP generated Literal packets with this +tag. With PGP 5.x, this packet has been reassigned and is reserved for use as +the Marker packet.
+
+Such a packet MUST be ignored when received.
+ +
-

new require("packet/marker")()

+

new (require("packet/marker"))()

@@ -74,7 +84,7 @@
Source:
@@ -127,7 +137,7 @@
Source:
@@ -297,7 +307,7 @@
Source:
@@ -360,13 +370,13 @@

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:56 GMT-0800 (PST)
diff --git a/doc/marker.js.html b/doc/marker.js.html index fc39cffe..2e235959 100644 --- a/doc/marker.js.html +++ b/doc/marker.js.html @@ -42,18 +42,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/marker */ /** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * + * Implementation of the strange "Marker packet" (Tag 10)<br/> + * <br/> * RFC4880 5.8: An experimental version of PGP used this packet as the Literal * packet, but no released version of PGP generated Literal packets with this * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * + * the Marker packet.<br/> + * <br/> * Such a packet MUST be ignored when received. + * @module packet/marker + */ + +/** + * @constructor */ module.exports = function () { /** @@ -68,8 +71,8 @@ module.exports = function () { * @return {module:packet/marker} Object representation */ this.read = function(bytes) { - if (bytes.charCodeAt(0) == 0x50 && // P - bytes.charCodeAt(1) == 0x47 && // G + if (bytes.charCodeAt(0) == 0x50 && // P + bytes.charCodeAt(1) == 0x47 && // G bytes.charCodeAt(2) == 0x50) // P return true; // marker packet does not contain "PGP" @@ -86,13 +89,13 @@ module.exports = function () {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/md5.html b/doc/md5.html index b7625cc9..e42c4ad3 100644 --- a/doc/md5.html +++ b/doc/md5.html @@ -35,6 +35,124 @@
+ + +
+

require("crypto/hash/md5")(entree)

+ + +
+
+ + +
+ MD5 hash +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
entree + + +String + + + + string to hash
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + @@ -62,7 +180,7 @@
Source:
@@ -83,6 +201,12 @@ +

Requires

+ + + @@ -105,13 +229,13 @@

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST)
diff --git a/doc/md5.js.html b/doc/md5.js.html index 7a1fb033..5e260d4e 100644 --- a/doc/md5.js.html +++ b/doc/md5.js.html @@ -39,11 +39,18 @@ * warranty of any kind. */ -/** @module crypto/hash/md5 */ +/** + * @requires util + * @module crypto/hash/md5 + */ -var util = require('../../util/util.js'); +var util = require('../../util'); -function MD5(entree) { +/** + * MD5 hash + * @param {String} entree string to hash + */ +module.exports = function (entree) { var hex = md5(entree); var bin = util.hex2bin(hex); return bin; @@ -136,11 +143,11 @@ function cmn(q, a, b, x, s, t) { } function ff(a, b, c, d, x, s, t) { - return cmn((b & c) | ((~b) & d), a, b, x, s, t); + return cmn((b & c) | ((~b) & d), a, b, x, s, t); } function gg(a, b, c, d, x, s, t) { - return cmn((b & d) | (c & (~d)), a, b, x, s, t); + return cmn((b & d) | (c & (~d)), a, b, x, s, t); } function hh(a, b, c, d, x, s, t) { @@ -204,7 +211,7 @@ function rhex(n) { var s = '', j = 0; for (; j < 4; j++) - s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; + s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; return s; } @@ -225,18 +232,16 @@ need the idiotic second function, generated by an if clause. */ function add32(a, b) { - return (a + b) & 0xFFFFFFFF; + return (a + b) & 0xFFFFFFFF; } if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { function add32(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), + var lsw = (x & 0xFFFF) + (y & 0xFFFF), msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); + return (msw << 16) | (lsw & 0xFFFF); } } - -module.exports = MD5
@@ -247,13 +252,13 @@ module.exports = MD5
diff --git a/doc/message.js.html b/doc/message.js.html index 2bcd3764..88f1d507 100644 --- a/doc/message.js.html +++ b/doc/message.js.html @@ -42,14 +42,20 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module message */ +/** + * @requires config + * @requires crypto + * @requires encoding/armor + * @requires enums + * @requires packet + * @module message + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); -var crypto = require('./crypto'); -var util = require('./util'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'), + crypto = require('./crypto'); /** * @class @@ -139,7 +145,7 @@ Message.prototype.decrypt = function(privateKey) { */ Message.prototype.getLiteralData = function() { var literal = this.packets.findPacket(enums.packet.literal); - return literal && literal.data || null; + return literal && literal.data || null; }; /** @@ -288,6 +294,7 @@ Message.prototype.armor = function() { * reads an OpenPGP armored message and returns a message object * @param {String} armoredText text to be parsed * @return {module:message~Message} new message object + * @static */ function readArmored(armoredText) { //TODO how do we want to handle bad text? Exception throwing @@ -303,6 +310,7 @@ function readArmored(armoredText) { * creates new message object from text * @param {String} text * @return {module:message~Message} new message object + * @static */ function fromText(text) { var literalDataPacket = new packet.literal(); @@ -318,6 +326,7 @@ function fromText(text) { * creates new message object from binary data * @param {String} bytes * @return {module:message~Message} new message object + * @static */ function fromBinary(bytes) { var literalDataPacket = new packet.literal(); @@ -342,13 +351,13 @@ exports.fromBinary = fromBinary;
diff --git a/doc/module-armor.html b/doc/module-armor.html new file mode 100644 index 00000000..dae971d4 --- /dev/null +++ b/doc/module-armor.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: armor + + + + + + + + + + +
+ +

Module: armor

+ + + + + +
+ +
+

+ armor +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/doc/module-cleartext-CleartextMessage.html b/doc/module-cleartext-CleartextMessage.html index 60f6adc9..6a36c71b 100644 --- a/doc/module-cleartext-CleartextMessage.html +++ b/doc/module-cleartext-CleartextMessage.html @@ -153,7 +153,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -240,7 +240,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -331,7 +331,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -422,7 +422,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -561,7 +561,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -678,7 +678,7 @@ See http://tools.ietf.org/html/rfc4880#section-7
Source:
@@ -741,13 +741,13 @@ See http://tools.ietf.org/html/rfc4880#section-7
diff --git a/doc/module-cleartext.html b/doc/module-cleartext.html index 8d9609b3..b647874a 100644 --- a/doc/module-cleartext.html +++ b/doc/module-cleartext.html @@ -83,6 +83,18 @@ +

Requires

+ + +

Classes

@@ -103,7 +115,7 @@
-

<inner> readArmored(armoredText) → {module:cleartext~CleartextMessage}

+

<static> readArmored(armoredText) → {module:cleartext~CleartextMessage}

@@ -192,7 +204,7 @@
Source:
@@ -255,13 +267,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/module-config.html b/doc/module-config.html new file mode 100644 index 00000000..d12852ab --- /dev/null +++ b/doc/module-config.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: config + + + + + + + + + + +
+ +

Module: config

+ + + + + +
+ +
+

+ config +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-crypto.html b/doc/module-crypto.html new file mode 100644 index 00000000..9fee91f4 --- /dev/null +++ b/doc/module-crypto.html @@ -0,0 +1,530 @@ + + + + + JSDoc: Module: crypto + + + + + + + + + + +
+ +

Module: crypto

+ + + + + +
+ +
+

+ crypto +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + +

Members

+ +
+ +
+

<static> cfb

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> cipher

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> hash

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> pkcs1

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> publicKey

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> random

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> signature

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ +
+ + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-enums.html b/doc/module-enums.html new file mode 100644 index 00000000..d7317d05 --- /dev/null +++ b/doc/module-enums.html @@ -0,0 +1,4542 @@ + + + + + JSDoc: Module: enums + + + + + + + + + + +
+ +

Module: enums

+ + + + + +
+ +
+

+ enums +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + + + + + + + +

Members

+ +
+ +
+

<static, readonly> armor :Integer

+ + +
+
+ +
+ Armor type +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
multipart_section + + +Integer + + + + + + 0 + +
multipart_last + + +Integer + + + + + + 1 + +
signed + + +Integer + + + + + + 2 + +
message + + +Integer + + + + + + 3 + +
public_key + + +Integer + + + + + + 4 + +
private_key + + +Integer + + + + + + 5 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> compression :Integer

+ + +
+
+ +
+ RFC4880, section 9.3 +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
uncompressed + + +Integer + + + + + + 0 + +
zip + + +Integer + + + + + + 1 + + RFC1951
zlib + + +Integer + + + + + + 2 + + RFC1950
bzip2 + + +Integer + + + + + + 3 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> hash :Integer

+ + +
+
+ +
+ RFC4880, section 9.4 +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
md5 + + +Integer + + + + + + 1 + +
sha1 + + +Integer + + + + + + 2 + +
ripemd + + +Integer + + + + + + 3 + +
sha256 + + +Integer + + + + + + 8 + +
sha384 + + +Integer + + + + + + 9 + +
sha512 + + +Integer + + + + + + 10 + +
sha224 + + +Integer + + + + + + 11 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> keyFlags :Integer

+ + +
+
+ +
+ Key flags +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
certify_keys + + +Integer + + + + + + 1 + + 0x01 - This key may be used to certify other keys.
sign_data + + +Integer + + + + + + 2 + + 0x02 - This key may be used to sign data.
encrypt_communication + + +Integer + + + + + + 4 + + 0x04 - This key may be used to encrypt communications.
encrypt_storage + + +Integer + + + + + + 8 + + 0x08 - This key may be used to encrypt storage.
split_private_key + + +Integer + + + + + + 16 + + 0x10 - The private component of this key may have been split + by a secret-sharing mechanism.
authentication + + +Integer + + + + + + 32 + + 0x20 - This key may be used for authentication.
shared_private_key + + +Integer + + + + + + 128 + + 0x80 - The private component of this key may be in the + possession of more than one person.
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> keyStatus :Integer

+ + +
+
+ +
+ Key status +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
invalid + + +Integer + + + + + + 0 + +
expired + + +Integer + + + + + + 1 + +
revoked + + +Integer + + + + + + 2 + +
valid + + +Integer + + + + + + 3 + +
no_self_cert + + +Integer + + + + + + 4 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> literal :Integer

+ + +
+
+ +
+ Data types in the literal packet +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
binary + + +Integer + + + + + + CALL + + Binary data 'b'
text + + +Integer + + + + + + CALL + + Text data 't'
utf8 + + +Integer + + + + + + CALL + + Utf8 data 'u'
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> packet :Integer

+ + +
+
+ +
+ A list of packet types and numeric tags associated with them. +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
public_key_encrypted_session_key + + +Integer + + + + + + 1 + +
signature + + +Integer + + + + + + 2 + +
sym_encrypted_session_key + + +Integer + + + + + + 3 + +
one_pass_signature + + +Integer + + + + + + 4 + +
secret_key + + +Integer + + + + + + 5 + +
public_key + + +Integer + + + + + + 6 + +
secret_subkey + + +Integer + + + + + + 7 + +
compressed + + +Integer + + + + + + 8 + +
symmetrically_encrypted + + +Integer + + + + + + 9 + +
marker + + +Integer + + + + + + 10 + +
literal + + +Integer + + + + + + 11 + +
trust + + +Integer + + + + + + 12 + +
userid + + +Integer + + + + + + 13 + +
public_subkey + + +Integer + + + + + + 14 + +
user_attribute + + +Integer + + + + + + 17 + +
sym_encrypted_integrity_protected + + +Integer + + + + + + 18 + +
modification_detection_code + + +Integer + + + + + + 19 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> publicKey :Integer

+ + +
+
+ +
+ RFC4880, section 9.1 +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
rsa_encrypt_sign + + +Integer + + + + + + 1 + +
rsa_encrypt + + +Integer + + + + + + 2 + +
rsa_sign + + +Integer + + + + + + 3 + +
elgamal + + +Integer + + + + + + 16 + +
dsa + + +Integer + + + + + + 17 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> s2k :Integer

+ + +
+
+ +
+ A string to key specifier type +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
simple + + +Integer + + + + + + 0 + +
salted + + +Integer + + + + + + 1 + +
iterated + + +Integer + + + + + + 3 + +
gnu + + +Integer + + + + + + 101 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> signature :Integer

+ + +
+
+ +
+ One pass signature packet type +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
binary + + +Integer + + + + + + 0 + + 0x00: Signature of a binary document.
text + + +Integer + + + + + + 1 + + 0x01: Signature of a canonical text document.
+Canonicalyzing the document by converting line endings.
standalone + + +Integer + + + + + + 2 + + 0x02: Standalone signature.
+This signature is a signature of only its own subpacket contents. +It is calculated identically to a signature over a zero-lengh +binary document. Note that it doesn't make sense to have a V3 +standalone signature.
cert_generic + + +Integer + + + + + + 16 + + 0x10: Generic certification of a User ID and Public-Key packet.
+The issuer of this certification does not make any particular +assertion as to how well the certifier has checked that the owner +of the key is in fact the person described by the User ID.
cert_persona + + +Integer + + + + + + 17 + + 0x11: Persona certification of a User ID and Public-Key packet.
+The issuer of this certification has not done any verification of +the claim that the owner of this key is the User ID specified.
cert_casual + + +Integer + + + + + + 18 + + 0x12: Casual certification of a User ID and Public-Key packet.
+The issuer of this certification has done some casual +verification of the claim of identity.
cert_positive + + +Integer + + + + + + 19 + + 0x13: Positive certification of a User ID and Public-Key packet.
+The issuer of this certification has done substantial +verification of the claim of identity.
+
+Most OpenPGP implementations make their "key signatures" as 0x10 +certifications. Some implementations can issue 0x11-0x13 +certifications, but few differentiate between the types.
cert_revocation + + +Integer + + + + + + 48 + + 0x30: Certification revocation signature
+This signature revokes an earlier User ID certification signature +(signature class 0x10 through 0x13) or direct-key signature +(0x1F). It should be issued by the same key that issued the +revoked signature or an authorized revocation key. The signature +is computed over the same data as the certificate that it +revokes, and should have a later creation date than that +certificate.
subkey_binding + + +Integer + + + + + + 24 + + 0x18: Subkey Binding Signature
+This signature is a statement by the top-level signing key that +indicates that it owns the subkey. This signature is calculated +directly on the primary key and subkey, and not on any User ID or +other packets. A signature that binds a signing subkey MUST have +an Embedded Signature subpacket in this binding signature that +contains a 0x19 signature made by the signing subkey on the +primary key and subkey.
key_binding + + +Integer + + + + + + 25 + + 0x19: Primary Key Binding Signature
+This signature is a statement by a signing subkey, indicating +that it is owned by the primary key and subkey. This signature +is calculated the same way as a 0x18 signature: directly on the +primary key and subkey, and not on any User ID or other packets.
+
+When a signature is made over a key, the hash data starts with the +octet 0x99, followed by a two-octet length of the key, and then body +of the key packet. (Note that this is an old-style packet header for +a key packet with two-octet length.) A subkey binding signature +(type 0x18) or primary key binding signature (type 0x19) then hashes +the subkey using the same format as the main key (also using 0x99 as +the first octet).
key + + +Integer + + + + + + 31 + + 0x1F: Signature directly on a key
+This signature is calculated directly on a key. It binds the +information in the Signature subpackets to the key, and is +appropriate to be used for subpackets that provide information +about the key, such as the Revocation Key subpacket. It is also +appropriate for statements that non-self certifiers want to make +about the key itself, rather than the binding between a key and a +name.
key_revocation + + +Integer + + + + + + 32 + + 0x20: Key revocation signature
+The signature is calculated directly on the key being revoked. A +revoked key is not to be used. Only revocation signatures by the +key being revoked, or by an authorized revocation key, should be +considered valid revocation signatures.a
subkey_revocation + + +Integer + + + + + + 40 + + 0x28: Subkey revocation signature
+The signature is calculated directly on the subkey being revoked. +A revoked subkey is not to be used. Only revocation signatures +by the top-level signature key that is bound to this subkey, or +by an authorized revocation key, should be considered valid +revocation signatures.
+
+Key revocation signatures (types 0x20 and 0x28) +hash only the key being revoked.
timestamp + + +Integer + + + + + + 64 + + 0x40: Timestamp signature.
+This signature is only meaningful for the timestamp contained in +it.
third_party + + +Integer + + + + + + 80 + + 0x50: Third-Party Confirmation signature.
+This signature is a signature over some other OpenPGP Signature +packet(s). It is analogous to a notary seal on the signed data. +A third-party signature SHOULD include Signature Target +subpacket(s) to give easy identification. Note that we really do +mean SHOULD. There are plausible uses for this (such as a blind +party that only sees the signature, not the key or source +document) that cannot include a target subpacket.
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> signatureSubpacket :Integer

+ + +
+
+ +
+ Signature subpacket type +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
signature_creation_time + + +Integer + + + + + + 2 + +
signature_expiration_time + + +Integer + + + + + + 3 + +
exportable_certification + + +Integer + + + + + + 4 + +
trust_signature + + +Integer + + + + + + 5 + +
regular_expression + + +Integer + + + + + + 6 + +
revocable + + +Integer + + + + + + 7 + +
key_expiration_time + + +Integer + + + + + + 9 + +
placeholder_backwards_compatibility + + +Integer + + + + + + 10 + +
preferred_symmetric_algorithms + + +Integer + + + + + + 11 + +
revocation_key + + +Integer + + + + + + 12 + +
issuer + + +Integer + + + + + + 16 + +
notation_data + + +Integer + + + + + + 20 + +
preferred_hash_algorithms + + +Integer + + + + + + 21 + +
preferred_compression_algorithms + + +Integer + + + + + + 22 + +
key_server_preferences + + +Integer + + + + + + 23 + +
preferred_key_server + + +Integer + + + + + + 24 + +
primary_user_id + + +Integer + + + + + + 25 + +
policy_uri + + +Integer + + + + + + 26 + +
key_flags + + +Integer + + + + + + 27 + +
signers_user_id + + +Integer + + + + + + 28 + +
reason_for_revocation + + +Integer + + + + + + 29 + +
features + + +Integer + + + + + + 30 + +
signature_target + + +Integer + + + + + + 31 + +
embedded_signature + + +Integer + + + + + + 32 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

<static, readonly> symmetric :Integer

+ + +
+
+ +
+ RFC4880, section 9.2 +
+ + + +
Type:
+
    +
  • + +Integer + + +
  • +
+ + + +
+ + +
Properties:
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
plaintext + + +Integer + + + + + + 0 + +
idea + + +Integer + + + + + + 1 + + Not implemented!
tripledes + + +Integer + + + + + + 2 + +
cast5 + + +Integer + + + + + + 3 + +
blowfish + + +Integer + + + + + + 4 + +
aes128 + + +Integer + + + + + + 7 + +
aes192 + + +Integer + + + + + + 8 + +
aes256 + + +Integer + + + + + + 9 + +
twofish + + +Integer + + + + + + 10 + +
+ + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

<static> read()

+ + +
+
+ + +
+ Converts from an integer to string. +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> write()

+ + +
+
+ + +
+ Asserts validity and converts from string/integer to integer. +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:54 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-key-Key.html b/doc/module-key-Key.html index 59b7fac0..7e863ae8 100644 --- a/doc/module-key-Key.html +++ b/doc/module-key-Key.html @@ -129,7 +129,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -216,7 +216,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -355,7 +355,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -517,7 +517,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -567,7 +567,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
-

getAllKeyPackets() → {Array.<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)>}

+

getAllKeyPackets() → {Array.<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)>}

@@ -608,7 +608,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -640,7 +640,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
-Array.<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)> +Array.<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)>
@@ -654,7 +654,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
-

getEncryptionKeyPacket() → {module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key|null}

+

getEncryptionKeyPacket() → {module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key|null}

@@ -695,7 +695,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -740,7 +740,7 @@ Can contain additional subkeys, signatures, user ids, user attributes. module:packet/secret_key | -module:packet/public_key +module:packet/public_key | null @@ -798,7 +798,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -844,7 +844,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
-

getKeyPacket() → {module:packet/secret_key|module:packet/public_key|null}

+

getKeyPacket() → {module:packet/secret_key|module:packet/public_key|null}

@@ -885,7 +885,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -920,7 +920,7 @@ Can contain additional subkeys, signatures, user ids, user attributes. module:packet/secret_key | -module:packet/public_key +module:packet/public_key | null @@ -978,7 +978,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1067,7 +1067,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1206,7 +1206,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1258,7 +1258,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
-

getPublicKeyPacket(keyIds) → {module:packet/public_subkey|module:packet/public_key|null}

+

getPublicKeyPacket(keyIds) → {module:packet/public_subkey|module:packet/public_key|null}

@@ -1347,7 +1347,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1382,7 +1382,7 @@ Can contain additional subkeys, signatures, user ids, user attributes. module:packet/public_subkey | -module:packet/public_key +module:packet/public_key | null @@ -1440,7 +1440,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1537,7 +1537,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1624,7 +1624,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1715,7 +1715,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1802,7 +1802,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -1937,7 +1937,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -2006,7 +2006,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -2097,7 +2097,7 @@ Can contain additional subkeys, signatures, user ids, user attributes.
Source:
@@ -2189,7 +2189,7 @@ and valid self signature
Source:
@@ -2252,13 +2252,13 @@ and valid self signature
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-key-SubKey.html b/doc/module-key-SubKey.html index 7571bff2..b15da579 100644 --- a/doc/module-key-SubKey.html +++ b/doc/module-key-SubKey.html @@ -80,7 +80,7 @@
Source:
@@ -177,7 +177,7 @@ module:packet/secret_key | -module:packet/public_key +module:packet/public_key @@ -218,7 +218,7 @@
Source:
@@ -315,7 +315,7 @@ module:packet/secret_key | -module:packet/public_key +module:packet/public_key @@ -356,7 +356,7 @@
Source:
@@ -443,7 +443,7 @@
Source:
@@ -531,7 +531,7 @@ and valid binding signature
Source:
@@ -594,13 +594,13 @@ and valid binding signature
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-key-User.html b/doc/module-key-User.html index 38859e31..186eb2e9 100644 --- a/doc/module-key-User.html +++ b/doc/module-key-User.html @@ -80,7 +80,7 @@
Source:
@@ -177,7 +177,7 @@ module:packet/secret_key | -module:packet/public_key +module:packet/public_key @@ -218,7 +218,7 @@
Source:
@@ -342,7 +342,7 @@ module:packet/secret_key | -module:packet/public_key +module:packet/public_key @@ -383,7 +383,7 @@
Source:
@@ -474,7 +474,7 @@
Source:
@@ -572,7 +572,7 @@ and validity of self signature module:packet/secret_key | -module:packet/public_key +module:packet/public_key @@ -613,7 +613,7 @@ and validity of self signature
Source:
@@ -676,13 +676,13 @@ and validity of self signature
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-key.html b/doc/module-key.html index 7c2459bb..2a381775 100644 --- a/doc/module-key.html +++ b/doc/module-key.html @@ -83,6 +83,18 @@ +

Requires

+ + +

Classes

@@ -109,7 +121,7 @@
-

<inner> generate(keyType, numBits, userId, passphrase) → {module:key~Key}

+

<static> generate(keyType, numBits, userId, passphrase) → {module:key~Key}

@@ -269,7 +281,7 @@ Primary and subkey will be of same type.
Source:
@@ -315,7 +327,7 @@ Primary and subkey will be of same type.
-

<inner> readArmored(armoredText) → {Object}

+

<static> readArmored(armoredText) → {Object}

@@ -404,7 +416,7 @@ Primary and subkey will be of same type.
Source:
@@ -467,13 +479,13 @@ Primary and subkey will be of same type.
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-keyid.html b/doc/module-keyid.html new file mode 100644 index 00000000..06d81306 --- /dev/null +++ b/doc/module-keyid.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: keyid + + + + + + + + + + +
+ +

Module: keyid

+ + + + + +
+ +
+

+ keyid +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-message-Message.html b/doc/module-message-Message.html index 26231aa9..958e1511 100644 --- a/doc/module-message-Message.html +++ b/doc/module-message-Message.html @@ -130,7 +130,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -217,7 +217,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -356,7 +356,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -495,7 +495,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -586,7 +586,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -677,7 +677,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -771,7 +771,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -862,7 +862,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -1004,7 +1004,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -1095,7 +1095,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -1234,7 +1234,7 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
Source:
@@ -1297,13 +1297,13 @@ See http://tools.ietf.org/html/rfc4880#section-11.3
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-message.html b/doc/module-message.html index a43135e8..9625eb55 100644 --- a/doc/module-message.html +++ b/doc/module-message.html @@ -83,6 +83,20 @@ +

Requires

+ + +

Classes

@@ -103,7 +117,7 @@
-

<inner> fromBinary(bytes) → {module:message~Message}

+

<static> fromBinary(bytes) → {module:message~Message}

@@ -192,7 +206,7 @@
Source:
@@ -242,7 +256,7 @@
-

<inner> fromText(text) → {module:message~Message}

+

<static> fromText(text) → {module:message~Message}

@@ -331,7 +345,7 @@
Source:
@@ -381,7 +395,7 @@
-

<inner> readArmored(armoredText) → {module:message~Message}

+

<static> readArmored(armoredText) → {module:message~Message}

@@ -470,7 +484,7 @@
Source:
@@ -533,13 +547,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-mpi.html b/doc/module-mpi.html new file mode 100644 index 00000000..254e23dc --- /dev/null +++ b/doc/module-mpi.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: mpi + + + + + + + + + + +
+ +

Module: mpi

+ + + + + +
+ +
+

+ mpi +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-openpgp.html b/doc/module-openpgp.html index 219a655c..3d26f5c8 100644 --- a/doc/module-openpgp.html +++ b/doc/module-openpgp.html @@ -62,7 +62,7 @@
Source:
@@ -83,6 +83,22 @@ +

Requires

+ + + @@ -96,7 +112,7 @@
-

<inner> decryptAndVerifyMessage(privateKey, publicKeys, message) → {Object}

+

<static> decryptAndVerifyMessage(privateKey, publicKeys, message) → {Object}

@@ -231,7 +247,7 @@
Source:
@@ -282,7 +298,7 @@
-

<inner> decryptMessage(privateKey, message) → {String|null}

+

<static> decryptMessage(privateKey, message) → {String|null}

@@ -394,7 +410,7 @@
Source:
@@ -448,7 +464,7 @@
-

<inner> encryptMessage(keys, text) → {String}

+

<static> encryptMessage(keys, text) → {String}

@@ -560,7 +576,7 @@
Source:
@@ -610,7 +626,7 @@
-

<inner> generateKeyPair(keyType, numBits, userId, passphrase) → {Object}

+

<static> generateKeyPair(keyType, numBits, userId, passphrase) → {Object}

@@ -770,7 +786,7 @@ Primary and subkey will be of same type.
Source:
@@ -820,7 +836,7 @@ Primary and subkey will be of same type.
-

<inner> signAndEncryptMessage(publicKeys, privateKey, text) → {String}

+

<static> signAndEncryptMessage(publicKeys, privateKey, text) → {String}

@@ -955,7 +971,7 @@ Primary and subkey will be of same type.
Source:
@@ -1005,7 +1021,7 @@ Primary and subkey will be of same type.
-

<inner> signClearMessage(privateKeys, text) → {String}

+

<static> signClearMessage(privateKeys, text) → {String}

@@ -1117,7 +1133,7 @@ Primary and subkey will be of same type.
Source:
@@ -1167,7 +1183,7 @@ Primary and subkey will be of same type.
-

<inner> verifyClearSignedMessage(publicKeys, message) → {Object}

+

<static> verifyClearSignedMessage(publicKeys, message) → {Object}

@@ -1279,7 +1295,7 @@ Primary and subkey will be of same type.
Source:
@@ -1342,13 +1358,13 @@ Primary and subkey will be of same type.
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST)
diff --git a/doc/module-packet.html b/doc/module-packet.html new file mode 100644 index 00000000..f04a3120 --- /dev/null +++ b/doc/module-packet.html @@ -0,0 +1,1042 @@ + + + + + JSDoc: Module: packet + + + + + + + + + + +
+ +

Module: packet

+ + + + + +
+ +
+

+ packet +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + +

Requires

+ + + + + + + + + +

Members

+ +
+ +
+

<static> compressed

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> literal

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> marker

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> one_pass_signature

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> public_key

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> public_key_encrypted_session_key

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> public_subkey

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> secret_key

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> secret_subkey

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> signature

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sym_encrypted_integrity_protected

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> sym_encrypted_session_key

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> symmetrically_encrypted

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> trust

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> user_attribute

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ + + +
+

<static> userid

+ + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + +
+ +
+ + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:55 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-s2k.html b/doc/module-s2k.html new file mode 100644 index 00000000..eeecdf81 --- /dev/null +++ b/doc/module-s2k.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: s2k + + + + + + + + + + +
+ +

Module: s2k

+ + + + + +
+ +
+

+ s2k +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/module-util.html b/doc/module-util.html new file mode 100644 index 00000000..82c3a1b6 --- /dev/null +++ b/doc/module-util.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Module: util + + + + + + + + + + +
+ +

Module: util

+ + + + + +
+ +
+

+ util +

+ +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST) +
+ + + + + \ No newline at end of file diff --git a/doc/mpi.html b/doc/mpi.html index 73e12ad5..41e0f435 100644 --- a/doc/mpi.html +++ b/doc/mpi.html @@ -36,8 +36,18 @@
+
Implementation of type MPI (RFC4880 3.2)
+
+Multiprecision integers (also called MPIs) are unsigned integers used +to hold large integers such as the ones used in cryptographic +calculations. +An MPI consists of two pieces: a two-octet scalar that is the length +of the MPI in bits followed by a string of octets that contain the +actual integer.
+ +
-

new require("type/mpi")()

+

new (require("type/mpi"))()

@@ -74,7 +84,7 @@
Source:
@@ -148,6 +158,14 @@ +

Requires

+ + + @@ -195,7 +213,7 @@
Source:
@@ -219,7 +237,7 @@
-

read(input, position, len) → {module:type/mpi}

+

read(input) → {Integer}

@@ -281,54 +299,6 @@ - - - - position - - - - - -Integer - - - - - - - - - - Position to start reading from the input -string - - - - - - - len - - - - - -Integer - - - - - - - - - - Length of the packet or the remaining length of -input at position - - - @@ -356,7 +326,7 @@ input at position
Source:
@@ -381,7 +351,7 @@ input at position
- Object representation + Length of data read
@@ -392,7 +362,7 @@ input at position
-module:type/mpi +Integer
@@ -447,7 +417,7 @@ input at position
Source:
@@ -510,13 +480,13 @@ input at position

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST)
diff --git a/doc/mpi.js.html b/doc/mpi.js.html index 554a983e..05483c27 100644 --- a/doc/mpi.js.html +++ b/doc/mpi.js.html @@ -47,20 +47,25 @@ // - MPI size: (a << 8) | b // - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) -/** @module type/mpi */ - -var BigInteger = require('../crypto/public_key/jsbn.js'), - util = require('../util'); - /** - * @class - * @classdescImplementation of type MPI (RFC4880 3.2) + * Implementation of type MPI (RFC4880 3.2)<br/> + * <br/> * Multiprecision integers (also called MPIs) are unsigned integers used * to hold large integers such as the ones used in cryptographic * calculations. * An MPI consists of two pieces: a two-octet scalar that is the length * of the MPI in bits followed by a string of octets that contain the * actual integer. + * @requires crypto/public_key/jsbn + * @requires util + * @module type/mpi + */ + +var BigInteger = require('../crypto/public_key/jsbn.js'), + util = require('../util'); + +/** + * @constructor */ module.exports = function mpi() { /** An implementation dependent integer */ @@ -69,11 +74,7 @@ module.exports = function mpi() { /** * Parsing function for a mpi (RFC 4880 3.2). * @param {String} input Payload of mpi data - * @param {Integer} position Position to start reading from the input - * string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {module:type/mpi} Object representation + * @return {Integer} Length of data read */ this.read = function(bytes) { var bits = (bytes.charCodeAt(0) << 8) | bytes.charCodeAt(1); @@ -94,19 +95,19 @@ module.exports = function mpi() { this.fromBytes(raw); return 2 + bytelen; - } + }; this.fromBytes = function(bytes) { this.data = new BigInteger(util.hexstrdump(bytes), 16); - } + }; this.toBytes = function() { return this.write().substr(2); - } + }; this.byteLength = function() { return this.toBytes().length; - } + }; /** * Converts the mpi object to a string as specified in RFC4880 3.2 @@ -114,15 +115,15 @@ module.exports = function mpi() { */ this.write = function() { return this.data.toMPI(); - } + }; this.toBigInteger = function() { return this.data.clone(); - } + }; this.fromBigInteger = function(bn) { this.data = bn.clone(); - } + }; }
@@ -134,13 +135,13 @@ module.exports = function mpi() {
diff --git a/doc/one_pass_signature.html b/doc/one_pass_signature.html index 73556e70..77d877de 100644 --- a/doc/one_pass_signature.html +++ b/doc/one_pass_signature.html @@ -36,8 +36,18 @@
+
Implementation of the One-Pass Signature Packets (Tag 4)
+
+RFC4880 5.4: +The One-Pass Signature packet precedes the signed data and contains +enough information to allow the receiver to begin calculating any +hashes needed to verify the signature. It allows the Signature +packet to be placed at the end of the message, so that the signer +can compute the entire signed message in one pass.
+ +
-

new require("packet/one_pass_signature")()

+

new (require("packet/one_pass_signature"))()

@@ -74,7 +84,7 @@
Source:
@@ -148,6 +158,14 @@ +

Requires

+ + + @@ -250,7 +268,7 @@
Source:
@@ -341,7 +359,7 @@
Source:
@@ -404,13 +422,13 @@

diff --git a/doc/one_pass_signature.js.html b/doc/one_pass_signature.js.html index d6f4f1f0..c77a071b 100644 --- a/doc/one_pass_signature.js.html +++ b/doc/one_pass_signature.js.html @@ -42,24 +42,27 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/one_pass_signature */ - -var enums = require('../enums.js'), - type_keyid = require('../type/keyid.js'); - /** - * @class - * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) - * + * Implementation of the One-Pass Signature Packets (Tag 4)<br/> + * <br/> * RFC4880 5.4: * The One-Pass Signature packet precedes the signed data and contains * enough information to allow the receiver to begin calculating any * hashes needed to verify the signature. It allows the Signature * packet to be placed at the end of the message, so that the signer * can compute the entire signed message in one pass. - */ + * @requires enums + * @requires type/keyid + * @module packet/one_pass_signature +*/ -module.exports = function one_pass_signature() { +var enums = require('../enums.js'), + type_keyid = require('../type/keyid.js'); + +/** + * @constructor + */ +module.exports = function () { this.version = null; // A one-octet version number. The current version is 3. this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) @@ -127,13 +130,13 @@ module.exports = function one_pass_signature() {
diff --git a/doc/openpgp.js.html b/doc/openpgp.js.html index ca66d135..d9c27f61 100644 --- a/doc/openpgp.js.html +++ b/doc/openpgp.js.html @@ -48,15 +48,23 @@ * for extending and developing on top of the base library. */ -/** @module openpgp */ +/** + * @requires cleartext + * @requires config + * @requires encoding/armor + * @requires enums + * @requires message + * @requires packet + * @module openpgp + */ -var armor = require('./encoding/armor.js'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var config = require('./config'); -var message = require('./message.js'); -var cleartext = require('./cleartext.js'); -var key = require('./key.js'); +var armor = require('./encoding/armor.js'), + packet = require('./packet'), + enums = require('./enums.js'), + config = require('./config'), + message = require('./message.js'), + cleartext = require('./cleartext.js'), + key = require('./key.js'); /** @@ -64,6 +72,7 @@ var key = require('./key.js'); * @param {Array<module:key~Key>} keys array of keys, used to encrypt the message * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function encryptMessage(keys, text) { var msg = message.fromText(text); @@ -78,6 +87,7 @@ function encryptMessage(keys, text) { * @param {module:key~Key} privateKey private key with decrypted secret key data for signing * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function signAndEncryptMessage(publicKeys, privateKey, text) { var msg = message.fromText(text); @@ -93,6 +103,7 @@ function signAndEncryptMessage(publicKeys, privateKey, text) { * @param {module:message~Message} message the message object with the encrypted data * @return {(String|null)} decrypted message as as native JavaScript string * or null if no literal data found + * @static */ function decryptMessage(privateKey, message) { message = message.decrypt(privateKey); @@ -107,6 +118,7 @@ function decryptMessage(privateKey, message) { * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * decrypted message as as native JavaScript string * with verified signatures or null if no literal data found + * @static */ function decryptAndVerifyMessage(privateKey, publicKeys, message) { var result = {}; @@ -124,6 +136,7 @@ function decryptAndVerifyMessage(privateKey, publicKeys, message) { * @param {Array<module:key~Key>} privateKeys private key with decrypted secret key data to sign cleartext * @param {String} text cleartext * @return {String} ASCII armored message + * @static */ function signClearMessage(privateKeys, text) { var cleartextMessage = new cleartext.CleartextMessage(text); @@ -137,6 +150,7 @@ function signClearMessage(privateKeys, text) { * @param {module:cleartext~CleartextMessage} message cleartext message object with signatures * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * cleartext with status of verified signatures + * @static */ function verifyClearSignedMessage(publicKeys, message) { var result = {}; @@ -157,6 +171,7 @@ function verifyClearSignedMessage(publicKeys, message) { * @param {String} userId assumes already in form of "User Name <username@email.com>" * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {Object} {key: Array<module:key~Key>, privateKeyArmored: Array<String>, publicKeyArmored: Array<String>} + * @static */ function generateKeyPair(keyType, numBits, userId, passphrase) { var result = {}; @@ -184,13 +199,13 @@ exports.generateKeyPair = generateKeyPair;
diff --git a/doc/packet.html b/doc/packet.html index fdc9b6c7..8d1498aa 100644 --- a/doc/packet.html +++ b/doc/packet.html @@ -83,6 +83,14 @@ +

Requires

+ + + @@ -231,7 +239,7 @@
Source:
@@ -394,7 +402,7 @@ string
Source:
@@ -557,7 +565,7 @@ string
Source:
@@ -697,7 +705,7 @@ string
Source:
@@ -760,13 +768,13 @@ string
diff --git a/doc/packet.js.html b/doc/packet.js.html index 13e2c333..876a0844 100644 --- a/doc/packet.js.html +++ b/doc/packet.js.html @@ -42,7 +42,11 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/packet */ +/** + * @requires enums + * @requires util + * @module packet/packet + */ var enums = require('../enums.js'), util = require('../util'); @@ -83,13 +87,13 @@ module.exports = { var result = ""; if (length < 192) { result += String.fromCharCode(length); - } else if (length > 191 && length < 8384) { + } else if (length > 191 && length < 8384) { /* * let a = (total data packet length) - 192 let bc = two octet * representation of a let d = b + 192 */ result += String.fromCharCode(((length - 192) >> 8) + 192); - result += String.fromCharCode((length - 192) & 0xFF); + result += String.fromCharCode((length - 192) & 0xFF); } else { result += String.fromCharCode(255); result += util.writeNumber(length, 4); @@ -146,7 +150,7 @@ module.exports = { */ read: function(input, position, len) { // some sanity checks - if (input == null || input.length <= position || input.substring(position).length < 2 || (input.charCodeAt(position) & + if (input == null || input.length <= position || input.substring(position).length < 2 || (input.charCodeAt(position) & 0x80) == 0) { throw new Error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."); } @@ -156,18 +160,18 @@ module.exports = { var packet_length; format = 0; // 0 = old format; 1 = new format - if ((input.charCodeAt(mypos) & 0x40) != 0) { + if ((input.charCodeAt(mypos) & 0x40) != 0) { format = 1; } var packet_length_type; if (format) { // new format header - tag = input.charCodeAt(mypos) & 0x3F; // bit 5-0 + tag = input.charCodeAt(mypos) & 0x3F; // bit 5-0 } else { // old format header - tag = (input.charCodeAt(mypos) & 0x3F) >> 2; // bit 5-2 - packet_length_type = input.charCodeAt(mypos) & 0x03; // bit 1-0 + tag = (input.charCodeAt(mypos) & 0x3F) >> 2; // bit 5-2 + packet_length_type = input.charCodeAt(mypos) & 0x03; // bit 1-0 } // header octet parsing done @@ -220,12 +224,12 @@ module.exports = { packet_length = input.charCodeAt(mypos++); util.print_debug("1 byte length:" + packet_length); // 4.2.2.2. Two-Octet Lengths - } else if (input.charCodeAt(mypos) >= 192 && input.charCodeAt(mypos) < 224) { + } else if (input.charCodeAt(mypos) >= 192 && input.charCodeAt(mypos) < 224) { packet_length = ((input.charCodeAt(mypos++) - 192) << 8) + (input.charCodeAt(mypos++)) + 192; util.print_debug("2 byte length:" + packet_length); // 4.2.2.4. Partial Body Lengths - } else if (input.charCodeAt(mypos) > 223 && input.charCodeAt(mypos) < 255) { - packet_length = 1 << (input.charCodeAt(mypos++) & 0x1F); + } else if (input.charCodeAt(mypos) > 223 && input.charCodeAt(mypos) < 255) { + packet_length = 1 << (input.charCodeAt(mypos++) & 0x1F); util.print_debug("4 byte length:" + packet_length); // EEEK, we're reading the full data here... var mypos2 = mypos + packet_length; @@ -237,14 +241,14 @@ module.exports = { bodydata += input.substring(mypos2, mypos2 + tmplen); mypos2 += tmplen; break; - } else if (input.charCodeAt(mypos2) >= 192 && input.charCodeAt(mypos2) < 224) { + } else if (input.charCodeAt(mypos2) >= 192 && input.charCodeAt(mypos2) < 224) { var tmplen = ((input.charCodeAt(mypos2++) - 192) << 8) + (input.charCodeAt(mypos2++)) + 192; packet_length += tmplen; bodydata += input.substring(mypos2, mypos2 + tmplen); mypos2 += tmplen; break; - } else if (input.charCodeAt(mypos2) > 223 && input.charCodeAt(mypos2) < 255) { - var tmplen = 1 << (input.charCodeAt(mypos2++) & 0x1F); + } else if (input.charCodeAt(mypos2) > 223 && input.charCodeAt(mypos2) < 255) { + var tmplen = 1 << (input.charCodeAt(mypos2++) & 0x1F); packet_length += tmplen; bodydata += input.substring(mypos2, mypos2 + tmplen); mypos2 += tmplen; @@ -294,13 +298,13 @@ module.exports = {
diff --git a/doc/packetlist.html b/doc/packetlist.html index 1f113361..4fede89a 100644 --- a/doc/packetlist.html +++ b/doc/packetlist.html @@ -36,8 +36,13 @@
+
This class represents a list of openpgp packets. +Take care when iterating over it - the packets themselves +are stored as numerical indices.
+ +
-

new require("packet/packetlist")()

+

new (require("packet/packetlist"))()

@@ -74,7 +79,7 @@
Source:
@@ -148,6 +153,16 @@ +

Requires

+ + + @@ -205,7 +220,7 @@
Source:
@@ -270,7 +285,7 @@
Source:
@@ -339,7 +354,7 @@
Source:
@@ -408,7 +423,7 @@
Source:
@@ -525,7 +540,7 @@
Source:
@@ -615,7 +630,7 @@
Source:
@@ -684,7 +699,7 @@
Source:
@@ -754,7 +769,7 @@ writing to packetlist[i] directly will result in an error.
Source:
@@ -782,7 +797,7 @@ writing to packetlist[i] directly will result in an error.
-

read(An)

+

read(A)

@@ -824,13 +839,13 @@ writing to packetlist[i] directly will result in an error. - An + A -openpgp_byte_array +String @@ -840,7 +855,7 @@ writing to packetlist[i] directly will result in an error. - array of bytes. + binary string of bytes. @@ -871,7 +886,7 @@ writing to packetlist[i] directly will result in an error.
Source:
@@ -940,7 +955,7 @@ writing to packetlist[i] directly will result in an error.
Source:
@@ -968,7 +983,7 @@ writing to packetlist[i] directly will result in an error.
-

write() → {openpgp_byte_array}

+

write() → {String}

@@ -1010,7 +1025,7 @@ class instance.
Source:
@@ -1035,7 +1050,7 @@ class instance.
- An array of bytes containing valid openpgp packets. + A binary string of bytes containing valid openpgp packets.
@@ -1046,7 +1061,7 @@ class instance.
-openpgp_byte_array +String
@@ -1073,13 +1088,13 @@ class instance.

diff --git a/doc/packetlist.js.html b/doc/packetlist.js.html index 26129b97..dfdeb987 100644 --- a/doc/packetlist.js.html +++ b/doc/packetlist.js.html @@ -25,19 +25,24 @@
-
/** @module packet/packetlist */
+            
/**
+ * This class represents a list of openpgp packets.
+ * Take care when iterating over it - the packets themselves
+ * are stored as numerical indices.
+ * @requires enums
+ * @requires packet
+ * @requires packet/packet
+ * @module packet/packetlist
+ */
 
 var packetParser = require('./packet.js'),
   packets = require('./all_packets.js'),
   enums = require('../enums.js');
 
 /**
- * @class
- * @classdesc This class represents a list of openpgp packets.
- * Take care when iterating over it - the packets themselves
- * are stored as numerical indices.
+ * @constructor
  */
-module.exports = function packetlist() {
+module.exports = packetlist = function () {
   /** The number of packets contained within the list.
    * @readonly
    * @type {Integer} */
@@ -45,7 +50,7 @@ module.exports = function packetlist() {
 
   /**
    * Reads a stream of binary data and interprents it as a list of packets.
-   * @param {openpgp_byte_array} An array of bytes.
+   * @param {String} A binary string of bytes.
    */
   this.read = function(bytes) {
     var i = 0;
@@ -66,7 +71,7 @@ module.exports = function packetlist() {
   /**
    * Creates a binary representation of openpgp objects contained within the
    * class instance.
-   * @returns {openpgp_byte_array} An array of bytes containing valid openpgp packets.
+   * @returns {String} A binary string of bytes containing valid openpgp packets.
    */
   this.write = function() {
     var bytes = '';
@@ -207,13 +212,13 @@ module.exports = function packetlist() {
 
 
 
 
 
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/pkcs1.html b/doc/pkcs1.html index e91f2011..a4887724 100644 --- a/doc/pkcs1.html +++ b/doc/pkcs1.html @@ -38,6 +38,8 @@ +
PKCS1 encoding
+
@@ -83,6 +85,20 @@ +

Requires

+ + + @@ -130,7 +146,7 @@
Source:
@@ -163,13 +179,13 @@
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST)
diff --git a/doc/pkcs1.js.html b/doc/pkcs1.js.html index ab2e75db..0cd1a255 100644 --- a/doc/pkcs1.js.html +++ b/doc/pkcs1.js.html @@ -42,7 +42,15 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module crypto/pkcs1 */ +/** + * PKCS1 encoding + * @requires crypto/crypto + * @requires crypto/hash + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/pkcs1 + */ /** * ASN1 object identifiers for hashes (See RFC4880 5.2.2) @@ -51,8 +59,8 @@ hash_headers = new Array(); hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 ]; -hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; +hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 ]; @@ -66,7 +74,6 @@ hash_headers[11] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x00, 0x04, 0x1C ]; - var crypto = require('./crypto.js'), random = require('./random.js'), util = require('../util'), @@ -106,10 +113,10 @@ module.exports = { if (message.length < 12 || message.charCodeAt(0) != 0 || message.charCodeAt(1) != 2) return -1; var i = 2; - while (message.charCodeAt(i) != 0 && message.length > i) + while (message.charCodeAt(i) != 0 && message.length > i) i++; return message.substring(i + 1, message.length); - }, + } }, emsa: { @@ -153,7 +160,7 @@ module.exports = { while (data.charCodeAt(i) == 0xFF) i++; if (data.charCodeAt(i++) != 0) return -1; var j = 0; - for (j = 0; j < hash_headers[algo].length && j + i < data.length; j++) { + for (j = 0; j < hash_headers[algo].length && j + i < data.length; j++) { if (data.charCodeAt(j + i) != hash_headers[algo][j]) return -1; } i += j; @@ -172,13 +179,13 @@ module.exports = {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/public_key.html b/doc/public_key.html index 10f2b122..8da964dd 100644 --- a/doc/public_key.html +++ b/doc/public_key.html @@ -2,7 +2,7 @@ - JSDoc: Module: packet/public_key + JSDoc: Module: crypto/public_key @@ -17,7 +17,7 @@
-

Module: packet/public_key

+

Module: crypto/public_key

@@ -27,7 +27,7 @@

- packet/public_key + crypto/public_key

@@ -35,71 +35,6 @@
- -
-

new require("packet/public_key")()

- - -
-
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - @@ -127,7 +62,7 @@
Source:
@@ -148,6 +83,16 @@ +

Requires

+ + + @@ -159,28 +104,14 @@
-

algorithm :openpgp.publickey

+

<static> dsa

-
- Public key algorithm -
- -
Type:
-
    -
  • - -openpgp.publickey - - -
  • -
-
@@ -205,13 +136,20 @@
Source:
+
See:
+
+ +
+
@@ -223,28 +161,14 @@
-

created :Date

+

<static> elgamal

-
- Key creation date. -
- -
Type:
-
    -
  • - -Date - - -
  • -
-
@@ -269,13 +193,20 @@
Source:
+
See:
+
+ +
+
@@ -287,114 +218,51 @@
-

mpi :module:type/mpi

+

<static> rsa

-
- A list of multiprecision integers -
+ + + + +
+ + -
Type:
+ + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

readPublicKey

- - -
-
- -
- Internal Parser for public keys as specified in RFC 4880 section -5.5.2 Public-Key Packet Formats -called by read_tag<num> -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - +
@@ -408,192 +276,6 @@ called by read_tag<num> -

Methods

- -
- -
-

getFingerprint() → {String}

- - -
-
- - -
- Calculates the fingerprint of the key -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- A string containing the fingerprint -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

getKeyId() → {String}

- - -
-
- - -
- Calculates the key id of the key -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- A 8 byte key id -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- -
- @@ -608,13 +290,13 @@ called by read_tag<num>

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:53 GMT-0800 (PST)
diff --git a/doc/public_key.js.html b/doc/public_key.js.html index f9952bcd..211bb6f0 100644 --- a/doc/public_key.js.html +++ b/doc/public_key.js.html @@ -42,7 +42,20 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)<br/> + * <br/> + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key + */ var util = require('../util'), type_mpi = require('../type/mpi.js'), @@ -51,15 +64,9 @@ var util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. + * @constructor */ -module.exports = function packet_public_key() { +module.exports = function () { this.version = 4; /** Key creation date. * @type {Date} */ @@ -68,7 +75,7 @@ module.exports = function packet_public_key() { * @type {module:type/mpi} */ this.mpi = []; /** Public key algorithm - * @type {openpgp.publickey} */ + * @type {module:enums.publicKey} */ this.algorithm = 'rsa_sign'; // time in days (V3 only) this.expirationTimeV3 = 0; @@ -77,13 +84,11 @@ module.exports = function packet_public_key() { /** * Internal Parser for public keys as specified in RFC 4880 section * 5.5.2 Public-Key Packet Formats - * called by read_tag&lt;num&gt; + * called by read_tag<num> * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input * @return {Object} This object with attributes set by the parser */ - this.readPublicKey = this.read = function(bytes) { + this.read = function(bytes) { var pos = 0; // A one-octet version number (3 or 4). this.version = bytes.charCodeAt(pos++); @@ -109,7 +114,7 @@ module.exports = function packet_public_key() { var bmpi = bytes.substr(pos); var p = 0; - for (var i = 0; i < mpicount && p < bmpi.length; i++) { + for (var i = 0; i < mpicount && p < bmpi.length; i++) { this.mpi[i] = new type_mpi(); @@ -124,19 +129,22 @@ module.exports = function packet_public_key() { } else { throw new Error('Version ' + version + ' of the key packet is unsupported.'); } - } + }; - /* + /** + * Alias of read() + * @function module:packet/public_key#readPublicKey + * @see module:packet/public_key#read + */ + this.readPublicKey = this.read; + + /** * Same as write_private_key, but has less information because of * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, + * @return {Object} {body: [string]OpenPGP packet body contents, * header: [string] OpenPGP packet header, string: [string] header+body} */ - this.writePublicKey = this.write = function() { + this.write = function() { // Version var result = String.fromCharCode(this.version); result += util.writeDate(this.created); @@ -152,16 +160,25 @@ module.exports = function packet_public_key() { } return result; - } + }; - // Write an old version packet - it's used by some of the internal routines. + /** + * Alias of write() + * @function module:packet/public_key#writePublicKey + * @see module:packet/public_key#write + */ + this.writePublicKey = this.write; + + /** + * Write an old version packet - it's used by some of the internal routines. + */ this.writeOld = function() { var bytes = this.writePublicKey(); return String.fromCharCode(0x99) + util.writeNumber(bytes.length, 2) + bytes; - } + }; /** * Calculates the key id of the key @@ -175,7 +192,7 @@ module.exports = function packet_public_key() { keyid.read(this.mpi[0].write().substr(-8)); } return keyid; - } + }; /** * Calculates the fingerprint of the key @@ -193,9 +210,8 @@ module.exports = function packet_public_key() { } return crypto.hash.md5(toHash) } - } - -} + }; +};
@@ -206,13 +222,13 @@ module.exports = function packet_public_key() {
diff --git a/doc/public_key_.html b/doc/public_key_.html new file mode 100644 index 00000000..9ed3fe29 --- /dev/null +++ b/doc/public_key_.html @@ -0,0 +1,1044 @@ + + + + + JSDoc: Module: packet/public_key + + + + + + + + + + +
+ +

Module: packet/public_key

+ + + + + +
+ +
+

+ packet/public_key +

+ +
+ +
+
+ + +
Implementation of the Key Material Packet (Tag 5,6,7,14)
+
+RFC4480 5.5: +A key material packet contains all the information about a public or +private key. There are four variants of this packet type, and two +major versions. Consequently, this section is complex.
+ + +
+

new (require("packet/public_key"))()

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + +

Requires

+ + + + + + + + + +

Members

+ +
+ +
+

algorithm :module:enums.publicKey

+ + +
+
+ +
+ Public key algorithm +
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

created :Date

+ + +
+
+ +
+ Key creation date. +
+ + + +
Type:
+
    +
  • + +Date + + +
  • +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

mpi :module:type/mpi

+ + +
+
+ +
+ A list of multiprecision integers +
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

getFingerprint() → {String}

+ + +
+
+ + +
+ Calculates the fingerprint of the key +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A string containing the fingerprint +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

getKeyId() → {String}

+ + +
+
+ + +
+ Calculates the key id of the key +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A 8 byte key id +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

read(input) → {Object}

+ + +
+
+ + +
+ Internal Parser for public keys as specified in RFC 4880 section +5.5.2 Public-Key Packet Formats +called by read_tag<num> +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
input + + +String + + + + Input string to read the packet from
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ This object with attributes set by the parser +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + +
+ + + +
+

readPublicKey()

+ + +
+
+ + +
+ Alias of read() +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ + + +
+

write() → {Object}

+ + +
+
+ + +
+ Same as write_private_key, but has less information because of +public key. +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ {body: [string]OpenPGP packet body contents, +header: [string] OpenPGP packet header, string: [string] header+body} +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + +
+ + + +
+

writeOld()

+ + +
+
+ + +
+ Write an old version packet - it's used by some of the internal routines. +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

writePublicKey()

+ + +
+
+ + +
+ Alias of write() +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/doc/public_key_encrypted_session_key.html b/doc/public_key_encrypted_session_key.html index bed1f62c..229d0198 100644 --- a/doc/public_key_encrypted_session_key.html +++ b/doc/public_key_encrypted_session_key.html @@ -36,8 +36,23 @@
+
Public-Key Encrypted Session Key Packets (Tag 1)
+
+RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key +used to encrypt a message. Zero or more Public-Key Encrypted Session Key +packets and/or Symmetric-Key Encrypted Session Key packets may precede a +Symmetrically Encrypted Data Packet, which holds an encrypted message. The +message is encrypted with the session key, and the session key is itself +encrypted and stored in the Encrypted Session Key packet(s). The +Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted +Session Key packet for each OpenPGP key to which the message is encrypted. +The recipient of the message finds a session key that is encrypted to their +public key, decrypts the session key, and then uses the session key to +decrypt the message.
+ +
-

new require("packet/public_key_encrypted_session_key")()

+

new (require("packet/public_key_encrypted_session_key"))()

@@ -74,7 +89,7 @@
Source:
@@ -148,6 +163,20 @@ +

Requires

+ + + @@ -201,7 +230,7 @@
Source:
@@ -315,7 +344,7 @@ packets (tag 1)
Source:
@@ -501,7 +530,7 @@ packets (tag 1)
Source:
@@ -735,7 +764,7 @@ packets (tag 1)
Source:
@@ -798,13 +827,13 @@ packets (tag 1)

diff --git a/doc/public_key_encrypted_session_key.js.html b/doc/public_key_encrypted_session_key.js.html index f5d2b39a..90667288 100644 --- a/doc/public_key_encrypted_session_key.js.html +++ b/doc/public_key_encrypted_session_key.js.html @@ -42,19 +42,9 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key_encrypted_session_key */ - -var type_keyid = require('../type/keyid.js'), - util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)<br/> + * <br/> * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -66,8 +56,24 @@ var type_keyid = require('../type/keyid.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key_encrypted_session_key */ -module.exports = function packet_public_key_encrypted_session_key() { + +var type_keyid = require('../type/keyid.js'), + util = require('../util'), + type_mpi = require('../type/mpi.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.version = 3; this.publicKeyId = new type_keyid(); @@ -117,7 +123,7 @@ module.exports = function packet_public_key_encrypted_session_key() { i += mpi.read(bytes.substr(i)); this.encrypted.push(mpi); } - } + }; /** * Create a string representation of a tag 1 packet @@ -149,7 +155,7 @@ module.exports = function packet_public_key_encrypted_session_key() { } return result; - } + }; this.encrypt = function(key) { var data = String.fromCharCode( @@ -168,7 +174,7 @@ module.exports = function packet_public_key_encrypted_session_key() { this.publicKeyAlgorithm, key.mpi, mpi); - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -199,7 +205,7 @@ module.exports = function packet_public_key_encrypted_session_key() { this.sessionKeyAlgorithm = enums.read(enums.symmetric, decoded.charCodeAt(0)); } - } + }; };
@@ -211,13 +217,13 @@ module.exports = function packet_public_key_encrypted_session_key() {
diff --git a/doc/public_subkey.html b/doc/public_subkey.html index 2e8a55ce..b9d550d3 100644 --- a/doc/public_subkey.html +++ b/doc/public_subkey.html @@ -35,6 +35,72 @@
+ + +
+

new (require("packet/public_subkey"))()

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + @@ -83,6 +149,11 @@ +

Requires

+ + @@ -90,6 +161,894 @@ +

Members

+ +
+ +
+

algorithm :module:enums.publicKey

+ + +
+
+ +
+ Public key algorithm +
+ + + +
Type:
+ + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

created :Date

+ + +
+
+ +
+ Key creation date. +
+ + + +
Type:
+
    +
  • + +Date + + +
  • +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

mpi :module:type/mpi

+ + +
+
+ +
+ A list of multiprecision integers +
+ + + +
Type:
+ + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

getFingerprint() → {String}

+ + +
+
+ + +
+ Calculates the fingerprint of the key +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A string containing the fingerprint +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

getKeyId() → {String}

+ + +
+
+ + +
+ Calculates the key id of the key +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A 8 byte key id +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

read(input) → {Object}

+ + +
+
+ + +
+ Internal Parser for public keys as specified in RFC 4880 section +5.5.2 Public-Key Packet Formats +called by read_tag<num> +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
input + + +String + + + + Input string to read the packet from
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ This object with attributes set by the parser +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + +
+ + + +
+

readPublicKey()

+ + +
+
+ + +
+ Alias of read() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ + + +
+

write() → {Object}

+ + +
+
+ + +
+ Same as write_private_key, but has less information because of +public key. +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ {body: [string]OpenPGP packet body contents, +header: [string] OpenPGP packet header, string: [string] header+body} +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + +
+ + + +
+

writeOld()

+ + +
+
+ + +
+ Write an old version packet - it's used by some of the internal routines. +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

writePublicKey()

+ + +
+
+ + +
+ Alias of write() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ +
@@ -105,13 +1064,13 @@

diff --git a/doc/public_subkey.js.html b/doc/public_subkey.js.html index 2efe8642..8db82c72 100644 --- a/doc/public_subkey.js.html +++ b/doc/public_subkey.js.html @@ -42,12 +42,19 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_subkey */ +/** + * @requires packet/public_key + * @module packet/public_subkey + */ -var public_key = require('./public_key.js'); +var publicKey = require('./public_key.js'); -module.exports = function public_subkey() { - public_key.call(this); +/** + * @constructor + * @extends module:packet/public_key + */ +module.exports = function () { + publicKey.call(this); }
@@ -59,13 +66,13 @@ module.exports = function public_subkey() {
diff --git a/doc/random.html b/doc/random.html index 038d06ad..5a84681c 100644 --- a/doc/random.html +++ b/doc/random.html @@ -83,6 +83,12 @@ +

Requires

+ + + @@ -208,7 +214,7 @@
Source:
@@ -347,7 +353,7 @@
Source:
@@ -486,7 +492,7 @@
Source:
@@ -648,7 +654,7 @@
Source:
@@ -711,13 +717,13 @@
diff --git a/doc/random.js.html b/doc/random.js.html index e3e31f86..15e0af07 100644 --- a/doc/random.js.html +++ b/doc/random.js.html @@ -44,7 +44,10 @@ // The GPG4Browsers crypto interface -/** @module crypto/random */ +/** + * @requires type/mpi + * @module crypto/random + */ var type_mpi = require('../type/mpi.js'); @@ -82,15 +85,15 @@ module.exports = { var buf = new Uint32Array(1); window.crypto.getRandomValues(buf); var bits = ((to - from)).toString(2).length; - while ((buf[0] & (Math.pow(2, bits) - 1)) > (to - from)) + while ((buf[0] & (Math.pow(2, bits) - 1)) > (to - from)) window.crypto.getRandomValues(buf); - return from + (Math.abs(buf[0] & (Math.pow(2, bits) - 1))); + return from + (Math.abs(buf[0] & (Math.pow(2, bits) - 1))); }, getSecureRandomOctet: function() { var buf = new Uint32Array(1); window.crypto.getRandomValues(buf); - return buf[0] & 0xFF; + return buf[0] & 0xFF; }, /** @@ -108,7 +111,7 @@ module.exports = { if (bits % 8 > 0) { randomBits = String.fromCharCode( - (Math.pow(2, bits % 8) - 1) & + (Math.pow(2, bits % 8) - 1) & randomBits.charCodeAt(0)) + randomBits.substring(1); } @@ -141,13 +144,13 @@ module.exports = {
diff --git a/doc/ripe-md.html b/doc/ripe-md.html index b6c469d4..bab1c333 100644 --- a/doc/ripe-md.html +++ b/doc/ripe-md.html @@ -62,7 +62,7 @@
Source:
@@ -105,13 +105,13 @@
diff --git a/doc/ripe-md.js.html b/doc/ripe-md.js.html index ed6ff528..c055997d 100644 --- a/doc/ripe-md.js.html +++ b/doc/ripe-md.js.html @@ -47,7 +47,9 @@ /* Modified by Recurity Labs GmbH */ -/** @module crypto/hash/ripe-md */ +/** + * @module crypto/hash/ripe-md + */ var RMDsize = 160; var X = new Array(); @@ -61,7 +63,7 @@ function F(x, y, z) { } function G(x, y, z) { - return new Number((x & y) | (~x & z)); + return new Number((x & y) | (~x & z)); } function H(x, y, z) { @@ -69,7 +71,7 @@ function H(x, y, z) { } function I(x, y, z) { - return new Number((x & z) | (y & ~z)); + return new Number((x & z) | (y & ~z)); } function J(x, y, z) { @@ -117,11 +119,11 @@ function mixOneRound(a, b, c, d, e, x, s, roundNumber) { a = ROL(a, s) + e; c = ROL(c, 10); - a &= 0xffffffff; - b &= 0xffffffff; - c &= 0xffffffff; - d &= 0xffffffff; - e &= 0xffffffff; + a &= 0xffffffff; + b &= 0xffffffff; + c &= 0xffffffff; + d &= 0xffffffff; + e &= 0xffffffff; var retBlock = new Array(); retBlock[0] = a; @@ -245,13 +247,13 @@ function MDfinish(MDbuf, strptr, lswlen, mswlen) { zeroX(X); var j = 0; - for (var i = 0; i < (lswlen & 63); i++) { - X[i >>> 2] ^= (strptr.charCodeAt(j++) & 255) << (8 * (i & 3)); + for (var i = 0; i < (lswlen & 63); i++) { + X[i >>> 2] ^= (strptr.charCodeAt(j++) & 255) << (8 * (i & 3)); } - X[(lswlen >>> 2) & 15] ^= 1 << (8 * (lswlen & 3) + 7); + X[(lswlen >>> 2) & 15] ^= 1 << (8 * (lswlen & 3) + 7); - if ((lswlen & 63) > 55) { + if ((lswlen & 63) > 55) { compress(MDbuf, X); var X = new Array(16); zeroX(X); @@ -264,10 +266,10 @@ function MDfinish(MDbuf, strptr, lswlen, mswlen) { } function BYTES_TO_DWORD(fourChars) { - var tmp = (fourChars.charCodeAt(3) & 255) << 24; - tmp |= (fourChars.charCodeAt(2) & 255) << 16; - tmp |= (fourChars.charCodeAt(1) & 255) << 8; - tmp |= (fourChars.charCodeAt(0) & 255); + var tmp = (fourChars.charCodeAt(3) & 255) << 24; + tmp |= (fourChars.charCodeAt(2) & 255) << 16; + tmp |= (fourChars.charCodeAt(1) & 255) << 8; + tmp |= (fourChars.charCodeAt(0) & 255); return tmp; } @@ -296,10 +298,10 @@ function RMD(message) { MDfinish(MDbuf, message.substr(j), length, 0); for (var i = 0; i < RMDsize / 8; i += 4) { - hashcode[i] = MDbuf[i >>> 2] & 255; - hashcode[i + 1] = (MDbuf[i >>> 2] >>> 8) & 255; - hashcode[i + 2] = (MDbuf[i >>> 2] >>> 16) & 255; - hashcode[i + 3] = (MDbuf[i >>> 2] >>> 24) & 255; + hashcode[i] = MDbuf[i >>> 2] & 255; + hashcode[i + 1] = (MDbuf[i >>> 2] >>> 8) & 255; + hashcode[i + 2] = (MDbuf[i >>> 2] >>> 16) & 255; + hashcode[i + 3] = (MDbuf[i >>> 2] >>> 24) & 255; } return hashcode; @@ -328,13 +330,13 @@ module.exports = RMDstring;
diff --git a/doc/rsa.html b/doc/rsa.html index bf4bec6c..eab856db 100644 --- a/doc/rsa.html +++ b/doc/rsa.html @@ -83,6 +83,16 @@ +

Requires

+ + + @@ -105,13 +115,13 @@
diff --git a/doc/rsa.js.html b/doc/rsa.js.html index 160db3dc..f938e5e0 100644 --- a/doc/rsa.js.html +++ b/doc/rsa.js.html @@ -44,7 +44,12 @@ // // RSA implementation -/** @module crypto/public_key/rsa */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/rsa + */ var BigInteger = require('./jsbn.js'), util = require('../../util'), @@ -135,12 +140,12 @@ function RSA() { for (;;) { for (;;) { key.p = new BigInteger(B - qs, 1, rng); - if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) + if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) break; } for (;;) { key.q = new BigInteger(qs, 1, rng); - if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) + if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) break; } if (key.p.compareTo(key.q) <= 0) { @@ -182,13 +187,13 @@ module.exports = RSA;
diff --git a/doc/s2k.html b/doc/s2k.html index 8f660876..75526b45 100644 --- a/doc/s2k.html +++ b/doc/s2k.html @@ -36,8 +36,17 @@
+
Implementation of the String-to-key specifier (RFC4880 3.7)
+
+String-to-key (S2K) specifiers are used to convert passphrase strings +into symmetric-key encryption/decryption keys. They are used in two +places, currently: to encrypt the secret part of private keys in the +private keyring, and to convert passphrases to encryption keys for +symmetrically encrypted messages.
+ +
-

new require("type/s2k")()

+

new (require("type/s2k"))()

@@ -74,7 +83,7 @@
Source:
@@ -148,6 +157,16 @@ +

Requires

+ + + @@ -159,7 +178,7 @@
-

algorithm :openpgp.hash

+

algorithm :module:enums.hash

@@ -171,7 +190,7 @@

diff --git a/doc/s2k.js.html b/doc/s2k.js.html index b5cffd65..045b5c00 100644 --- a/doc/s2k.js.html +++ b/doc/s2k.js.html @@ -42,39 +42,45 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module type/s2k */ +/** + * Implementation of the String-to-key specifier (RFC4880 3.7)<br/> + * <br/> + * String-to-key (S2K) specifiers are used to convert passphrase strings + * into symmetric-key encryption/decryption keys. They are used in two + * places, currently: to encrypt the secret part of private keys in the + * private keyring, and to convert passphrases to encryption keys for + * symmetrically encrypted messages. + * @requires crypto + * @requires enums + * @requires util + * @module type/s2k + */ var enums = require('../enums.js'), util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. + * @constructor */ module.exports = function s2k() { - /** @type {openpgp.hash} */ + /** @type {module:enums.hash} */ this.algorithm = 'sha256'; - /** @type {module:type/s2k} */ + /** @type {module:enums.s2k} */ this.type = 'iterated'; this.c = 96; - /** Eight bytes of salt. - * @type {openpgp_byte_array} + /** Eight bytes of salt in a binary string. + * @type {String} */ this.salt = crypto.random.getRandomBytes(8); - // Exponen bias, defined in RFC4880 + // Exponent bias, defined in RFC4880 var expbias = 6; this.get_count = function() { - return (16 + (this.c & 15)) << ((this.c >> 4) + expbias); - } + return (16 + (this.c & 15)) << ((this.c >> 4) + expbias); + }; /** * Parsing function for a string-to-key specifier (RFC 4880 3.7). @@ -124,7 +130,7 @@ module.exports = function s2k() { } return i; - } + }; /** @@ -145,10 +151,10 @@ module.exports = function s2k() { bytes += this.salt; bytes += String.fromCharCode(this.c); break; - }; + } return bytes; - } + }; /** * Produces a key using the specified passphrase and the defined @@ -185,7 +191,7 @@ module.exports = function s2k() { isp = isp.substr(0, count); return crypto.hash.digest(algorithm, prefix + isp); - }; + } } var result = '', @@ -197,8 +203,8 @@ module.exports = function s2k() { } return result.substr(0, numBytes); - } -} + }; +}; @@ -209,13 +215,13 @@ module.exports = function s2k() {
diff --git a/doc/scripts/linenumber.js b/doc/scripts/linenumber.js index 613865d0..a0c570d5 100644 --- a/doc/scripts/linenumber.js +++ b/doc/scripts/linenumber.js @@ -9,7 +9,7 @@ numbered = source.innerHTML.split('\n'); numbered = numbered.map(function(item) { counter++; - return '' + item; + return '' + item; }); source.innerHTML = numbered.join('\n'); diff --git a/doc/secret_key.html b/doc/secret_key.html index 3bc9a900..da6797f8 100644 --- a/doc/secret_key.html +++ b/doc/secret_key.html @@ -36,8 +36,16 @@
+
Implementation of the Key Material Packet (Tag 5,6,7,14)
+
+RFC4480 5.5: +A key material packet contains all the information about a public or +private key. There are four variants of this packet type, and two +major versions. Consequently, this section is complex.
+ +
-

new require("packet/secret_key")()

+

new (require("packet/secret_key"))()

@@ -74,7 +82,7 @@
Source:
@@ -148,6 +156,22 @@ +

Requires

+ + + @@ -159,7 +183,7 @@
-

algorithm :openpgp.publickey :openpgp.publickey

+

algorithm :module:enums.publicKey

@@ -175,7 +199,7 @@
- - - - - - - -
-

mpi :module:type/mpi :module:type/mpi

- - -
-
- -
- A list of multiprecision integers -
- - - -
Type:
- - - - -
- - - - - - - -
Inherited From:
-
- - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

readPublicKey

- - -
-
- -
- Internal Parser for public keys as specified in RFC 4880 section -5.5.2 Public-Key Packet Formats -called by read_tag<num> -
- - - - - -
- - - - - - - -
Inherited From:
-
- - - - - - - - - - - - - -
Source:
-
@@ -442,9 +336,6 @@ called by read_tag<num>
Decrypts the private key MPIs which are needed to use the key. -openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be -false otherwise -a call to this function is not needed
@@ -526,7 +417,7 @@ as string
Source:
@@ -667,7 +558,7 @@ to key specifier
Source:
@@ -695,7 +586,7 @@ to key specifier
-

getFingerprint() → {String}() → {String}

+

getFingerprint() → {String}

@@ -724,7 +615,7 @@ to key specifier
Inherited From:
@@ -741,7 +632,7 @@ to key specifier
Source:
@@ -791,7 +682,7 @@ to key specifier
-

getKeyId() → {String}() → {String}

+

getKeyId() → {String}

@@ -820,7 +711,7 @@ to key specifier
Inherited From:
@@ -837,7 +728,7 @@ to key specifier
Source:
@@ -976,7 +867,7 @@ to key specifier
Source:
@@ -999,6 +890,87 @@ to key specifier +
+ + + +
+

readPublicKey()

+ + +
+
+ + +
+ Alias of read() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + +
@@ -1045,7 +1017,7 @@ to key specifier
Source:
@@ -1090,6 +1062,161 @@ to key specifier + + + + +
+

writeOld()

+ + +
+
+ + +
+ Write an old version packet - it's used by some of the internal routines. +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

writePublicKey()

+ + +
+
+ + +
+ Alias of write() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + +
@@ -1108,13 +1235,13 @@ to key specifier

diff --git a/doc/secret_key.js.html b/doc/secret_key.js.html index ba482499..32337674 100644 --- a/doc/secret_key.js.html +++ b/doc/secret_key.js.html @@ -42,7 +42,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)<br/> + * <br/> + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires packet/public_key + * @requires type/mpi + * @requires type/s2k + * @requires util + * @module packet/secret_key + */ var publicKey = require('./public_key.js'), enums = require('../enums.js'), @@ -52,14 +66,8 @@ var publicKey = require('./public_key.js'), type_s2k = require('../type/s2k.js'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) + * @constructor * @extends module:packet/public_key - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. */ module.exports = function () { publicKey.call(this); @@ -104,7 +112,7 @@ module.exports = function () { var j = 0; var mpi = []; - for (var i = 0; i < mpis && j < cleartext.length; i++) { + for (var i = 0; i < mpis && j < cleartext.length; i++) { mpi[i] = new type_mpi(); j += mpi[i].read(cleartext.substr(j)); } @@ -212,9 +220,8 @@ module.exports = function () { /** * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed + * @link module:packet/secret_key.isDecrypted should be + * false otherwise a call to this function is not needed * * @param {String} str_passphrase The passphrase for this private key * as string @@ -294,13 +301,13 @@ module.exports.prototype = new publicKey();
diff --git a/doc/secret_subkey.html b/doc/secret_subkey.html index 1d3abde5..d4ca274e 100644 --- a/doc/secret_subkey.html +++ b/doc/secret_subkey.html @@ -35,6 +35,72 @@
+ + +
+

new (require("packet/secret_subkey"))()

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + @@ -83,6 +149,11 @@ +

Requires

+ + @@ -90,6 +161,1068 @@ +

Members

+ +
+ +
+

algorithm :module:enums.publicKey

+ + +
+
+ +
+ Public key algorithm +
+ + + +
Type:
+ + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ + + +
+

created :Date

+ + +
+
+ +
+ Key creation date. +
+ + + +
Type:
+
    +
  • + +Date + + +
  • +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+ + + +

Methods

+ +
+ +
+

decrypt(str_passphrase) → {Boolean}

+ + +
+
+ + +
+ Decrypts the private key MPIs which are needed to use the key. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str_passphrase + + +String + + + + The passphrase for this private key +as string
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ True if the passphrase was correct or MPI already + decrypted; false if not +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + +
+ + + +
+

encrypt(passphrase)

+ + +
+
+ + +
+ Encrypt the payload. By default, we use aes256 and iterated, salted string +to key specifier +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
passphrase + + +String + + + +
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

getFingerprint() → {String}

+ + +
+
+ + +
+ Calculates the fingerprint of the key +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A string containing the fingerprint +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

getKeyId() → {String}

+ + +
+
+ + +
+ Calculates the key id of the key +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A 8 byte key id +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

read(bytes)

+ + +
+
+ + +
+ Internal parser for private keys as specified in RFC 4880 section 5.5.3 +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bytes + + +String + + + + Input string to read the packet from
+ + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

readPublicKey()

+ + +
+
+ + +
+ Alias of read() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ + + +
+

write() → {String}

+ + +
+
+ + +
+ Creates an OpenPGP key packet for the given key. +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A string of bytes containing the secret key OpenPGP packet +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

writeOld()

+ + +
+
+ + +
+ Write an old version packet - it's used by some of the internal routines. +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

writePublicKey()

+ + +
+
+ + +
+ Alias of write() +
+ + + + + + + + + +
+ + + + + + + +
Inherited From:
+
+ + + + + + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + +
+ +
@@ -105,13 +1238,13 @@

diff --git a/doc/secret_subkey.js.html b/doc/secret_subkey.js.html index 25b1b216..a29289cc 100644 --- a/doc/secret_subkey.js.html +++ b/doc/secret_subkey.js.html @@ -42,12 +42,19 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_subkey */ +/** + * @requires packet/secret_key + * @module packet/secret_subkey + */ -var secret_key = require('./secret_key.js'); +var secretKey = require('./secret_key.js'); -module.exports = function secret_subkey() { - secret_key.call(this); +/** + * @constructor + * @extends module:packet/secret_key + */ +module.exports = function () { + secretKey.call(this); }
@@ -59,13 +66,13 @@ module.exports = function secret_subkey() {
diff --git a/doc/sha.html b/doc/sha.html index 5c33e529..3d73616c 100644 --- a/doc/sha.html +++ b/doc/sha.html @@ -62,7 +62,7 @@
Source:
@@ -91,6 +91,355 @@ +

Methods

+ +
+ +
+

<static> sha1()

+ + +
+
+ + +
+ SHA1 hash +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> sha224()

+ + +
+
+ + +
+ SHA224 hash +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> sha256()

+ + +
+
+ + +
+ SHA256 hash +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> sha384()

+ + +
+
+ + +
+ SHA384 hash +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> sha512()

+ + +
+
+ + +
+ SHA512 hash +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ @@ -105,13 +454,13 @@
diff --git a/doc/sha.js.html b/doc/sha.js.html index 2674980e..2f563c4d 100644 --- a/doc/sha.js.html +++ b/doc/sha.js.html @@ -48,7 +48,9 @@ * - str_sha512 */ -/** @module crypto/hash/sha */ +/** + * @module crypto/hash/sha + */ var jsSHA = (function() { @@ -89,7 +91,7 @@ var jsSHA = (function() { i; for (i = 0; i < length; i += charSize) { - bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << + bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << (32 - charSize - (i % 32)); } @@ -135,8 +137,8 @@ var jsSHA = (function() { for (i = 0; i < length; i += 1) { srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8); - str += hex_tab.charAt((srcByte >> 4) & 0xF) + - hex_tab.charAt(srcByte & 0xF); + str += hex_tab.charAt((srcByte >> 4) & 0xF) + + hex_tab.charAt(srcByte & 0xF); } return str; @@ -159,12 +161,12 @@ var jsSHA = (function() { triplet; for (i = 0; i < length; i += 3) { - triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | - (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | - ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); + triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | + (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | + ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); for (j = 0; j < 4; j += 1) { if (i * 8 + j * 6 <= binarray.length * 32) { - str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); + str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); } else { str += b64pad; } @@ -180,7 +182,7 @@ var jsSHA = (function() { var str = ""; var mask = (1 << 8) - 1; for (var i = 0; i < bin.length * 32; i += 8) - str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); + str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); return str; }, /* @@ -280,7 +282,7 @@ var jsSHA = (function() { * @return The NIST specified output of the function */ ch_32 = function(x, y, z) { - return (x & y) ^ (~x & z); + return (x & y) ^ (~x & z); }, /* @@ -294,7 +296,7 @@ var jsSHA = (function() { */ ch_64 = function(x, y, z) { return new Int_64( - (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)); + (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)); }, /* @@ -307,7 +309,7 @@ var jsSHA = (function() { * @return The NIST specified output of the function */ maj_32 = function(x, y, z) { - return (x & y) ^ (x & z) ^ (y & z); + return (x & y) ^ (x & z) ^ (y & z); }, /* @@ -321,11 +323,11 @@ var jsSHA = (function() { */ maj_64 = function(x, y, z) { return new Int_64( - (x.highOrder & y.highOrder) ^ - (x.highOrder & z.highOrder) ^ - (y.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ - (x.lowOrder & z.lowOrder) ^ - (y.lowOrder & z.lowOrder)); + (x.highOrder & y.highOrder) ^ + (x.highOrder & z.highOrder) ^ + (y.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ + (x.lowOrder & z.lowOrder) ^ + (y.lowOrder & z.lowOrder)); }, /* @@ -450,10 +452,10 @@ var jsSHA = (function() { * @return The sum of x + y */ safeAdd_32_2 = function(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), + var lsw = (x & 0xFFFF) + (y & 0xFFFF), msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); }, /* @@ -468,11 +470,11 @@ var jsSHA = (function() { * @return The sum of a + b + c + d */ safeAdd_32_4 = function(a, b, c, d) { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + (lsw >>> 16); - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); }, /* @@ -488,12 +490,12 @@ var jsSHA = (function() { * @return The sum of a + b + c + d + e */ safeAdd_32_5 = function(a, b, c, d, e) { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + - (e & 0xFFFF), + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + + (e & 0xFFFF), msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + (e >>> 16) + (lsw >>> 16); - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); }, /* @@ -508,13 +510,13 @@ var jsSHA = (function() { safeAdd_64_2 = function(x, y) { var lsw, msw, lowOrder, highOrder; - lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); + lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); + lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); return new Int_64(highOrder, lowOrder); }, @@ -533,17 +535,17 @@ var jsSHA = (function() { safeAdd_64_4 = function(a, b, c, d) { var lsw, msw, lowOrder, highOrder; - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); return new Int_64(highOrder, lowOrder); }, @@ -563,21 +565,21 @@ var jsSHA = (function() { safeAdd_64_5 = function(a, b, c, d, e) { var lsw, msw, lowOrder, highOrder; - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + - (e.lowOrder & 0xFFFF); + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + + (e.lowOrder & 0xFFFF); msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + - (e.highOrder & 0xFFFF) + (msw >>> 16); + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + + (e.highOrder & 0xFFFF) + (msw >>> 16); msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (e.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); return new Int_64(highOrder, lowOrder); }, @@ -1082,12 +1084,12 @@ var jsSHA = (function() { /* For all variants, the block size is bigger than the output * size so there will never be a useful byte at the end of the * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; + keyToUse[lastArrayIndex] &= 0xFFFFFF00; } else if (blockByteSize > (keyBinLen / 8)) { /* If the blockByteSize is greater than the key length, there * will always be at LEAST one "useless" byte at the end of the * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; + keyToUse[lastArrayIndex] &= 0xFFFFFF00; } /* Create ipad and opad */ @@ -1121,23 +1123,28 @@ var jsSHA = (function() { }()); module.exports = { + /** SHA1 hash */ sha1: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-1", "ASCII"); }, + /** SHA224 hash */ sha224: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-224", "ASCII"); }, + /** SHA256 hash */ sha256: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-256", "ASCII"); }, + /** SHA384 hash */ sha384: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-384", "ASCII"); }, + /** SHA512 hash */ sha512: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-512", "ASCII"); @@ -1153,13 +1160,13 @@ module.exports = {
diff --git a/doc/signature.html b/doc/signature.html index 3db5c64e..92d9df80 100644 --- a/doc/signature.html +++ b/doc/signature.html @@ -83,6 +83,16 @@ +

Requires

+ + + @@ -279,7 +289,7 @@ integers which is used to sign the data
Source:
@@ -502,7 +512,7 @@ integers which is used to sign the data
Source:
@@ -565,13 +575,13 @@ integers which is used to sign the data
diff --git a/doc/signature.js.html b/doc/signature.js.html index 28c1fe17..1feb2ec5 100644 --- a/doc/signature.js.html +++ b/doc/signature.js.html @@ -25,7 +25,11 @@
-
/** @module crypto/signature */
+            
/**
+ * @requires crypto/hash
+ * @requires crypto/pkcs1
+ * @requires crypto/public_key
+ * @module crypto/signature */
 
 var publicKey = require('./public_key'),
   pkcs1 = require('./pkcs1.js'),
@@ -142,13 +146,13 @@ module.exports = {
 
 
 
 
 
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:51 GMT-0800 (PST)
diff --git a/doc/signature.js_.html b/doc/signature.js_.html index 578ce06f..7649ed5d 100644 --- a/doc/signature.js_.html +++ b/doc/signature.js_.html @@ -42,7 +42,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/signature */ +/** + * Implementation of the Signature Packet (Tag 2)<br/> + * <br/> + * RFC4480 5.2: + * A Signature packet describes a binding between some public key and + * some data. The most common signatures are a signature of a file or a + * block of text, and a signature that is a certification of a User ID. + * @requires crypto + * @requires enums + * @requires packet/packet + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/signature + */ var util = require('../util'), packet = require('./packet.js'), @@ -52,15 +66,9 @@ var util = require('../util'), type_keyid = require('../type/keyid.js'); /** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. + * @constructor */ -module.exports = function packet_signature() { +module.exports = packetSignature = function () { this.version = 4; this.signatureType = null; @@ -121,7 +129,7 @@ module.exports = function packet_signature() { case 3: // One-octet length of following hashed material. MUST be 5. if (bytes.charCodeAt(i++) != 5) - util.print_debug("openpgp.packet.signature.js\n" + + util.print_debug("packet/signature.js\n" + 'invalid One-octet length of following hashed material.' + 'MUST be 5. @:' + (i - 1)); @@ -381,7 +389,7 @@ module.exports = function packet_signature() { } // The leftwost bit denotes a "critical" packet, but we ignore it. - var type = bytes.charCodeAt(mypos++) & 0x7F; + var type = bytes.charCodeAt(mypos++) & 0x7F; // subpacket type switch (type) { @@ -518,7 +526,7 @@ module.exports = function packet_signature() { break; case 32: // Embedded Signature - this.embeddedSignature = new packet_signature(); + this.embeddedSignature = new packetSignature(); this.embeddedSignature.read(bytes.substr(mypos)); break; default: @@ -624,7 +632,7 @@ module.exports = function packet_signature() { var mpicount = 0; // Algorithm-Specific Fields for RSA signatures: // - multiprecision number (MPI) of RSA signature value m**d mod n. - if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) + if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) mpicount = 1; // Algorithm-Specific Fields for DSA signatures: // - MPI of DSA value r. @@ -667,13 +675,13 @@ module.exports = function packet_signature() {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/signature_.html b/doc/signature_.html index 87ad7583..00466098 100644 --- a/doc/signature_.html +++ b/doc/signature_.html @@ -36,8 +36,16 @@
+
Implementation of the Signature Packet (Tag 2)
+
+RFC4480 5.2: +A Signature packet describes a binding between some public key and +some data. The most common signatures are a signature of a file or a +block of text, and a signature that is a certification of a User ID.
+ +
-

new require("packet/signature")()

+

new (require("packet/signature"))()

@@ -74,7 +82,7 @@
Source:
@@ -148,6 +156,22 @@ +

Requires

+ + + @@ -202,7 +226,7 @@
Source:
@@ -387,7 +411,7 @@
Source:
@@ -549,7 +573,7 @@
Source:
@@ -654,7 +678,7 @@ module:packet/public_subkey | -module:packet/public_key +module:packet/public_key @@ -695,7 +719,7 @@
Source:
@@ -786,7 +810,7 @@
Source:
@@ -831,169 +855,6 @@ - - - - -
-

<inner> write_sub_packet(type, data) → {String}

- - -
-
- - -
- creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1) -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
type - - -Integer - - - - subpacket signature type. Signature types as described -in RFC4880 Section 5.2.3.2
data - - -String - - - - data to be included
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- a string-representation of a sub signature packet (See RFC 4880 5.2.3.1) -
- - - -
-
- Type -
-
- -String - - -
-
- - - -
@@ -1012,13 +873,13 @@ in RFC4880 Section 5.2.3.2

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:56 GMT-0800 (PST)
diff --git a/doc/styles/jsdoc-default.css b/doc/styles/jsdoc-default.css index 7afd6850..ea49f607 100644 --- a/doc/styles/jsdoc-default.css +++ b/doc/styles/jsdoc-default.css @@ -195,14 +195,12 @@ h6 font-family: Consolas, "Lucida Console", Monaco, monospace; } -.details { margin-top: 14px; border-left: 2px solid #DDD; } -.details dt { width:100px; float:left; padding-left: 10px; padding-top: 6px; } +.details { margin-top: 14px; } +.details dt { width:100px; float:left; border-left: 2px solid #DDD; padding-left: 10px; padding-top: 6px; } .details dd { margin-left: 50px; } .details ul { margin: 0; } .details ul { list-style-type: none; } .details li { margin-left: 30px; padding-top: 6px; } -.details pre.prettyprint { margin: 0 } -.details .object-value { padding-top: 0; } .description { margin-bottom: 1em; @@ -242,11 +240,6 @@ h6 border-left: 3px #ddd solid; } -.prettyprint code span.line -{ - display: inline-block; -} - .params, .props { border-spacing: 0; diff --git a/doc/sym_encrypted_integrity_protected.html b/doc/sym_encrypted_integrity_protected.html index c3097a68..872cd42b 100644 --- a/doc/sym_encrypted_integrity_protected.html +++ b/doc/sym_encrypted_integrity_protected.html @@ -36,8 +36,18 @@
+
Implementation of the Sym. Encrypted Integrity Protected Data +Packet (Tag 18)
+
+RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is +a variant of the Symmetrically Encrypted Data packet. It is a new feature +created for OpenPGP that addresses the problem of detecting a modification to +encrypted data. It is used in combination with a Modification Detection Code +packet.
+ +
-

new require("packet/sym_encrypted_integrity_protected")()

+

new (require("packet/sym_encrypted_integrity_protected"))()

@@ -74,7 +84,7 @@
Source:
@@ -148,6 +158,14 @@ +

Requires

+ + + @@ -195,7 +213,7 @@
Source:
@@ -261,7 +279,7 @@ should be discarded.
Source:
@@ -398,7 +416,7 @@ have been called before
Source:
@@ -461,13 +479,13 @@ have been called before

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST)
diff --git a/doc/sym_encrypted_integrity_protected.js.html b/doc/sym_encrypted_integrity_protected.js.html index dd342cff..aac06879 100644 --- a/doc/sym_encrypted_integrity_protected.js.html +++ b/doc/sym_encrypted_integrity_protected.js.html @@ -42,24 +42,27 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_integrity_protected */ - -var util = require('../util'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * + * Implementation of the Sym. Encrypted Integrity Protected Data + * Packet (Tag 18)<br/> + * <br/> * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is * a variant of the Symmetrically Encrypted Data packet. It is a new feature * created for OpenPGP that addresses the problem of detecting a modification to * encrypted data. It is used in combination with a Modification Detection Code * packet. + * @requires crypto + * @requires util + * @module packet/sym_encrypted_integrity_protected */ -module.exports = function packet_sym_encrypted_integrity_protected() { +var util = require('../util'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { /** The encrypted payload. */ this.encrypted = null; // string /** @@ -69,12 +72,11 @@ module.exports = function packet_sym_encrypted_integrity_protected() { * @type {Boolean} */ this.modification = false; - this.packets; + this.packets = null; this.read = function(bytes) { - // - A one-octet version number. The only currently defined value is - // 1. + // - A one-octet version number. The only currently defined value is 1. var version = bytes.charCodeAt(0); if (version != 1) { @@ -85,13 +87,13 @@ module.exports = function packet_sym_encrypted_integrity_protected() { // operating in Cipher Feedback mode with shift amount equal to the // block size of the cipher (CFB-n where n is the block size). this.encrypted = bytes.substr(1); - } + }; this.write = function() { return String.fromCharCode(1) // Version + this.encrypted; - } + }; this.encrypt = function(sessionKeyAlgorithm, key) { var bytes = this.packets.write() @@ -114,7 +116,7 @@ module.exports = function packet_sym_encrypted_integrity_protected() { this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false).substring(0, prefix.length + tohash.length); - } + }; /** * Decrypts the encrypted data contained in this object read_packet must @@ -142,7 +144,7 @@ module.exports = function packet_sym_encrypted_integrity_protected() { throw new Error('Modification detected.'); } else this.packets.read(decrypted.substr(0, decrypted.length - 22)); - } + }; };
@@ -154,13 +156,13 @@ module.exports = function packet_sym_encrypted_integrity_protected() {
- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:09 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:52 GMT-0800 (PST)
diff --git a/doc/sym_encrypted_session_key.html b/doc/sym_encrypted_session_key.html index 1b594253..1174e921 100644 --- a/doc/sym_encrypted_session_key.html +++ b/doc/sym_encrypted_session_key.html @@ -36,8 +36,23 @@
+
Public-Key Encrypted Session Key Packets (Tag 1)
+
+RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key +used to encrypt a message. Zero or more Public-Key Encrypted Session Key +packets and/or Symmetric-Key Encrypted Session Key packets may precede a +Symmetrically Encrypted Data Packet, which holds an encrypted message. The +message is encrypted with the session key, and the session key is itself +encrypted and stored in the Encrypted Session Key packet(s). The +Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted +Session Key packet for each OpenPGP key to which the message is encrypted. +The recipient of the message finds a session key that is encrypted to their +public key, decrypts the session key, and then uses the session key to +decrypt the message.
+ +
-

new require("packet/sym_encrypted_session_key")()

+

new (require("packet/sym_encrypted_session_key"))()

@@ -74,7 +89,7 @@
Source:
@@ -148,6 +163,16 @@ +

Requires

+ + + @@ -203,7 +228,7 @@ packets (tag 1)
Source:
@@ -389,7 +414,7 @@ packets (tag 1)
Source:
@@ -452,13 +477,13 @@ packets (tag 1)

- Documentation generated by JSDoc 3.3.0-alpha2 on Sun Dec 22 2013 23:43:10 GMT-0800 (PST) + Documentation generated by JSDoc 3.2.0 on Thu Dec 26 2013 22:42:57 GMT-0800 (PST)
diff --git a/doc/sym_encrypted_session_key.js.html b/doc/sym_encrypted_session_key.js.html index fa983e91..e862fe3c 100644 --- a/doc/sym_encrypted_session_key.js.html +++ b/doc/sym_encrypted_session_key.js.html @@ -42,16 +42,9 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_session_key */ - -var type_s2k = require('../type/s2k.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)<br/> + * <br/> * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -63,8 +56,20 @@ var type_s2k = require('../type/s2k.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/s2k + * @module packet/sym_encrypted_session_key */ -module.exports = function packet_sym_encrypted_session_key() { + +var type_s2k = require('../type/s2k.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 3; this.sessionKeyEncryptionAlgorithm = null; this.sessionKeyAlgorithm = 'aes256'; @@ -100,7 +105,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKeyEncryptionAlgorithm = algo } else this.sessionKeyAlgorithm = algo; - } + }; this.write = function() { var algo = this.encrypted == null ? @@ -114,7 +119,7 @@ module.exports = function packet_sym_encrypted_session_key() { if (this.encrypted != null) bytes += this.encrypted; return bytes; - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -143,7 +148,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKey = decrypted.substr(1); } - } + }; this.encrypt = function(passphrase) { var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); @@ -158,7 +163,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), this.sessionKeyEncryptionAlgorithm, key, private_key, true); - } + }; };
@@ -170,13 +175,13 @@ module.exports = function packet_sym_encrypted_session_key() {
diff --git a/doc/symmetrically_encrypted.html b/doc/symmetrically_encrypted.html index 1d0112a8..6dee336e 100644 --- a/doc/symmetrically_encrypted.html +++ b/doc/symmetrically_encrypted.html @@ -36,8 +36,17 @@
+
Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
+
+RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted +with a symmetric-key algorithm. When it has been decrypted, it contains other +packets (usually a literal data packet or compressed data packet, but in +theory other Symmetrically Encrypted Data packets or sequences of packets +that form whole OpenPGP messages).
+ +
-

new require("packet/symmetrically_encrypted")()

+

new (require("packet/symmetrically_encrypted"))()

@@ -74,7 +83,7 @@
Source:
@@ -148,6 +157,12 @@ +

Requires

+ + + @@ -205,7 +220,7 @@
Source:
@@ -342,7 +357,7 @@
Source:
@@ -363,16 +378,6 @@ -
Returns:
- - -
- The decrypted data; -
- - - - @@ -393,13 +398,13 @@

diff --git a/doc/symmetrically_encrypted.js.html b/doc/symmetrically_encrypted.js.html index f99eccc1..61d75397 100644 --- a/doc/symmetrically_encrypted.js.html +++ b/doc/symmetrically_encrypted.js.html @@ -42,34 +42,36 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/symmetrically_encrypted */ - -var crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) - * + * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)<br/> + * <br/> * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted * with a symmetric-key algorithm. When it has been decrypted, it contains other * packets (usually a literal data packet or compressed data packet, but in * theory other Symmetrically Encrypted Data packets or sequences of packets * that form whole OpenPGP messages). + * @requires crypto + * @module packet/symmetrically_encrypted */ -module.exports = function packet_symmetrically_encrypted() { +var crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.encrypted = null; /** Decrypted packets contained within. * @type {module:packet/packetlist} */ - this.packets; + this.packets = null; this.read = function(bytes) { this.encrypted = bytes; - } + }; this.write = function() { return this.encrypted; - } + }; /** * Symmetrically decrypt the packet data @@ -79,21 +81,20 @@ module.exports = function packet_symmetrically_encrypted() { * @param {String} key * Key as string with the corresponding length to the * algorithm - * @return The decrypted data; */ this.decrypt = function(sessionKeyAlgorithm, key) { var decrypted = crypto.cfb.decrypt( sessionKeyAlgorithm, key, this.encrypted, true); this.packets.read(decrypted); - } + }; this.encrypt = function(algo, key) { var data = this.packets.write(); this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(algo), algo, data, key, true); - } + }; }; @@ -105,13 +106,13 @@ module.exports = function packet_symmetrically_encrypted() {
diff --git a/doc/trust.html b/doc/trust.html new file mode 100644 index 00000000..28644f1c --- /dev/null +++ b/doc/trust.html @@ -0,0 +1,186 @@ + + + + + JSDoc: Module: packet/trust + + + + + + + + + + +
+ +

Module: packet/trust

+ + + + + +
+ +
+

+ packet/trust +

+ +
+ +
+
+ + + +
+

new (require("packet/trust"))()

+ + +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/doc/trust.js.html b/doc/trust.js.html new file mode 100644 index 00000000..e24da700 --- /dev/null +++ b/doc/trust.js.html @@ -0,0 +1,60 @@ + + + + + JSDoc: Source: packet/trust.js + + + + + + + + + + +
+ +

Source: packet/trust.js

+ + + + + +
+
+
/**
+ * @module packet/trust
+ */
+
+/**
+ * @constructor
+ */
+module.exports = function () {
+
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/doc/twofish.html b/doc/twofish.html index cdb2f681..f6ac21a9 100644 --- a/doc/twofish.html +++ b/doc/twofish.html @@ -62,7 +62,7 @@
Source:
@@ -105,13 +105,13 @@
diff --git a/doc/twofish.js.html b/doc/twofish.js.html index d02a9bc7..4dc9ad8d 100644 --- a/doc/twofish.js.html +++ b/doc/twofish.js.html @@ -45,7 +45,9 @@ * */ -/** @module crypto/cipher/twofish */ +/** + * @module crypto/cipher/twofish + */ @@ -56,11 +58,11 @@ var MAXINT = 0xFFFFFFFF; function rotb(b, n) { - return (b << n | b >>> (8 - n)) & 0xFF; + return (b << n | b >>> (8 - n)) & 0xFF; } function rotw(w, n) { - return (w << n | w >>> (32 - n)) & MAXINT; + return (w << n | w >>> (32 - n)) & MAXINT; } function getW(a, i) { @@ -68,15 +70,15 @@ function getW(a, i) { } function setW(a, i, w) { - a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF); + a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF); } function setWInv(a, i, w) { - a.splice(i, 4, (w >>> 24) & 0xFF, (w >>> 16) & 0xFF, (w >>> 8) & 0xFF, w & 0xFF); + a.splice(i, 4, (w >>> 24) & 0xFF, (w >>> 16) & 0xFF, (w >>> 8) & 0xFF, w & 0xFF); } function getB(x, n) { - return (x >>> (n * 8)) & 0xFF; + return (x >>> (n * 8)) & 0xFF; } function getNrBits(i) { @@ -160,26 +162,26 @@ function createTwofish() { ]; function ffm5b(x) { - return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3]; + return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3]; } function ffmEf(x) { - return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3]; + return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3]; } function mdsRem(p, q) { var i, t, u; for (i = 0; i < 8; i++) { t = q >>> 24; - q = ((q << 8) & MAXINT) | p >>> 24; - p = (p << 8) & MAXINT; + q = ((q << 8) & MAXINT) | p >>> 24; + p = (p << 8) & MAXINT; u = t << 1; - if (t & 128) { + if (t & 128) { u ^= 333; } q ^= t ^ (u << 16); u ^= t >>> 1; - if (t & 1) { + if (t & 1) { u ^= 166; } q ^= u << 24 | u << 8; @@ -190,7 +192,7 @@ function createTwofish() { function qp(n, x) { var a, b, c, d; a = x >> 4; - b = x & 15; + b = x & 15; c = q0[n][a ^ b]; d = q1[n][ror4[b] ^ ashx[a]]; return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; @@ -223,7 +225,7 @@ function createTwofish() { keyBytes = keyBytes.slice(0, 32); i = keyBytes.length; - while (i != 16 && i != 24 && i != 32) + while (i != 16 && i != 24 && i != 32) keyBytes[i++] = 0; for (i = 0; i < keyBytes.length; i += 4) { @@ -259,7 +261,7 @@ function createTwofish() { b = a + 0x1010101; a = hFun(a, meKey); b = rotw(hFun(b, moKey), 8); - tfsKey[i] = (a + b) & MAXINT; + tfsKey[i] = (a + b) & MAXINT; tfsKey[i + 1] = rotw(a + 2 * b, 9); } for (i = 0; i < 256; i++) { @@ -295,23 +297,23 @@ function createTwofish() { function tfsFrnd(r, blk) { var a = tfsG0(blk[0]); var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); - blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; + blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); + blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; a = tfsG0(blk[2]); b = tfsG1(blk[3]); - blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); - blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; + blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); + blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; } function tfsIrnd(i, blk) { var a = tfsG0(blk[0]); var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; - blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); + blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; + blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); a = tfsG0(blk[2]); b = tfsG1(blk[3]); - blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; - blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); + blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; + blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); } function tfsClose() { @@ -415,13 +417,13 @@ module.exports.blockSize = TF.prototype.blockSize = 16;
diff --git a/doc/user_attribute.html b/doc/user_attribute.html index c099a400..991ada72 100644 --- a/doc/user_attribute.html +++ b/doc/user_attribute.html @@ -36,8 +36,26 @@
+
Implementation of the User Attribute Packet (Tag 17)
+
+The User Attribute packet is a variation of the User ID packet. It +is capable of storing more types of data than the User ID packet, +which is limited to text. Like the User ID packet, a User Attribute +packet may be certified by the key owner ("self-signed") or any other +key owner who cares to certify it. Except as noted, a User Attribute +packet may be used anywhere that a User ID packet may be used. +
+While User Attribute packets are not a required part of the OpenPGP +standard, implementations SHOULD provide at least enough +compatibility to properly handle a certification signature on the +User Attribute packet. A simple way to do this is by treating the +User Attribute packet as a User ID packet with opaque contents, but +an implementation may use any method desired. +module packet/user_attribute
+ +
-

new require("packet/user_attribute")()

+

new (require("packet/user_attribute"))()

@@ -74,7 +92,7 @@
Source:
@@ -161,7 +179,7 @@
-

read(input, position, len) → {module:packet/user_attribute}

+

read(input)

@@ -223,52 +241,6 @@ - - - - position - - - - - -Integer - - - - - - - - - - position to start reading from the input string - - - - - - - len - - - - - -Integer - - - - - - - - - - length of the packet or the remaining length of input at position - - - @@ -296,7 +268,7 @@
Source:
@@ -317,28 +289,6 @@ -
Returns:
- - -
- object representation -
- - - -
-
- Type -
-
- -module:packet/user_attribute - - -
-
- - @@ -359,13 +309,13 @@

diff --git a/doc/user_attribute.js.html b/doc/user_attribute.js.html index ef800115..96b21b57 100644 --- a/doc/user_attribute.js.html +++ b/doc/user_attribute.js.html @@ -42,46 +42,50 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/user_attribute */ - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. +/** + * Implementation of the User Attribute Packet (Tag 17)<br/> + * <br/> + * The User Attribute packet is a variation of the User ID packet. It + * is capable of storing more types of data than the User ID packet, + * which is limited to text. Like the User ID packet, a User Attribute + * packet may be certified by the key owner ("self-signed") or any other + * key owner who cares to certify it. Except as noted, a User Attribute + * packet may be used anywhere that a User ID packet may be used. + * <br/> + * While User Attribute packets are not a required part of the OpenPGP + * standard, implementations SHOULD provide at least enough + * compatibility to properly handle a certification signature on the + * User Attribute packet. A simple way to do this is by treating the + * User Attribute packet as a User ID packet with opaque contents, but + * an implementation may use any method desired. + * module packet/user_attribute + * @module packet/user_attribute */ -module.exports = function packet_user_attribute() { + +var util = require('../util'), + packet = require('./packet.js'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 17; this.attributes = []; /** * parsing function for a user attribute packet (tag 17). * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {module:packet/user_attribute} object representation */ this.read = function(bytes) { var i = 0; while (i < bytes.length) { - var len = openpgp_packet.read_simple_length(bytes); - + var len = packet.readSimpleLength(bytes.substr(i)); i += len.offset; + this.attributes.push(bytes.substr(i, len.len)); i += len.len; } - } + }; }; @@ -93,13 +97,13 @@ module.exports = function packet_user_attribute() {
diff --git a/doc/userid.html b/doc/userid.html index dc20c46d..2c44854d 100644 --- a/doc/userid.html +++ b/doc/userid.html @@ -36,8 +36,17 @@
+
Implementation of the User ID Packet (Tag 13)
+
+A User ID packet consists of UTF-8 text that is intended to represent +the name and email address of the key holder. By convention, it +includes an RFC 2822 [RFC2822] mail name-addr, but there are no +restrictions on its content. The packet length in the header +specifies the length of the User ID.
+ +
-

new require("packet/userid")()

+

new (require("packet/userid"))()

@@ -74,7 +83,7 @@
Source:
@@ -148,6 +157,12 @@ +

Requires

+ + + @@ -206,7 +221,7 @@ John Doe
Source:
@@ -230,7 +245,7 @@ John Doe
-

read(input, position, len) → {module:packet/userid}

+

read(input)

@@ -292,53 +307,6 @@ John Doe - - - - position - - - - - -Integer - - - - - - - - - - position to start reading from the input string - - - - - - - len - - - - - -Integer - - - - - - - - - - length of the packet or the remaining length of input -at position - - - @@ -387,28 +355,6 @@ at position -
Returns:
- - -
- object representation -
- - - -
-
- Type -
-
- -module:packet/userid - - -
-
- - @@ -416,7 +362,7 @@ at position
-

write(user_id) → {String}

+

write() → {String}

@@ -433,54 +379,6 @@ at position -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
user_id - - -String - - - - the user id as string ("John Doe -
-
@@ -505,7 +403,7 @@ at position
Source:
@@ -568,13 +466,13 @@ at position

diff --git a/doc/userid.js.html b/doc/userid.js.html index 92011b23..d2f1f378 100644 --- a/doc/userid.js.html +++ b/doc/userid.js.html @@ -42,20 +42,24 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/userid */ - -var util = require('../util'); - /** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) + * Implementation of the User ID Packet (Tag 13)<br/> + * <br/> * A User ID packet consists of UTF-8 text that is intended to represent * the name and email address of the key holder. By convention, it * includes an RFC 2822 [RFC2822] mail name-addr, but there are no * restrictions on its content. The packet length in the header - * specifies the length of the User ID. + * specifies the length of the User ID. + * @requires util + * @module packet/userid */ -module.exports = function packet_userid() { + +var util = require('../util'); + +/** + * @constructor + */ +module.exports = function () { /** A string containing the user id. Usually in the form * John Doe <john@example.com> * @type {String} @@ -66,23 +70,18 @@ module.exports = function packet_userid() { /** * Parsing function for a user id packet (tag 13). * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input - * at position - * @return {module:packet/userid} object representation */ - this.read = function(bytes) { + this.read = function (bytes) { this.userid = util.decode_utf8(bytes); - } + }; /** * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe <john.doe@mail.us") * @return {String} string representation */ - this.write = function() { + this.write = function () { return util.encode_utf8(this.userid); - } + }; } @@ -94,13 +93,13 @@ module.exports = function packet_userid() {
diff --git a/doc/util-Util.html b/doc/util-Util.html deleted file mode 100644 index f9c33a54..00000000 --- a/doc/util-Util.html +++ /dev/null @@ -1,1878 +0,0 @@ - - - - - JSDoc: Class: Util - - - - - - - - - - -
- -

Class: Util

- - - - - -
- -
-

- module:util/util~ - - Util -

- -
Implementation of the util object
- -
- -
-
- - - - -
-

new Util()

- - -
-
- - -
- This object contains utility functions -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - -

Members

- -
- -
-

bin2str

- - -
-
- -
- Convert an array of integers(0.255) to a string -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- - - -
-

Uint8Array2str

- - -
-
- -
- Convert a Uint8Array to a string. This currently functions -the same as bin2str. -
- - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - -
- -
- - - -

Methods

- -
- -
-

calc_checksum(text) → {Integer}

- - -
-
- - -
- Calculates a 16bit sum of a string by adding each character -codes modulus 65535 -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
text - - -String - - - - String to create a sum of
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- An integer containing the sum of all character -codes % 65535 -
- - - -
-
- Type -
-
- -Integer - - -
-
- - - - -
- - - -
-

decode_utf8(utf8) → {String}

- - -
-
- - -
- Convert a string of utf8 bytes to a native javascript string -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
utf8 - - -String - - - - A valid squence of utf8 bytes
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- A native javascript string -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

encode_utf8(str) → {String}

- - -
-
- - -
- Convert a native javascript string to a string of utf8 bytes -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - The string to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- A valid squence of utf8 bytes -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

get_hashAlgorithmString() → {String}

- - -
-
- - -
- Return the algorithm type as string -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- String representing the message type -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

hex2bin(str) → {String}

- - -
-
- - -
- Create binary string from a hex encoded string -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - Hex string to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- String containing the binary values -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

hexidump(str) → {String}

- - -
-
- - -
- Creating a hex string from an binary array of integers (0..255) -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - Array of bytes to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Hexadecimal representation of the array -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

hexstrdump(str) → {String}

- - -
-
- - -
- Create hexstring from a binary -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - String to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- String containing the hexadecimal values -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
- - - -
-
- - -
- Helper function to print a debug message. Debug -messages are only printed if -openpgp.config.debug is set to true. -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - String of the debug message
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
- - - -
-
- - -
- Helper function to print a debug message. Debug -messages are only printed if -openpgp.config.debug is set to true. -Different than print_debug because will call hexstrdump iff necessary. -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - String of the debug message
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- - - -
-

shiftRight(value, bitcount) → {String}

- - -
-
- - -
- Shifting a string to n bits right -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
value - - -String - - - - The string to shift
bitcount - - -Integer - - - - Amount of bits to shift (MUST be smaller -than 9)
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- Resulting string. -
- - - -
-
- Type -
-
- -String - - -
-
- - - - -
- - - -
-

str2bin(str) → {Array.<Integer>}

- - -
-
- - -
- Convert a string to an array of integers(0.255) -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - String to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- An array of (binary) integers -
- - - -
-
- Type -
-
- -Array.<Integer> - - -
-
- - - - -
- - - -
-

str2Uint8Array(str) → {Uint8Array}

- - -
-
- - -
- Convert a string to a Uint8Array -
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
str - - -String - - - - String to convert
- - - -
- - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
- The array of (binary) integers -
- - - -
-
- Type -
-
- -Uint8Array - - -
-
- - - - -
- -
- - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/doc/util.html b/doc/util.html index 250527e3..b0df71d4 100644 --- a/doc/util.html +++ b/doc/util.html @@ -38,6 +38,8 @@ +
This object contains utility functions
+
@@ -83,25 +85,1911 @@ +

Requires

+ + -

Classes

+ + + + + + + +

Methods

-
Util
-
+ +
+

<static> bin2str(bin) → {String}

+ + +
+
+ + +
+ Convert an array of integers(0.255) to a string +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bin + + +Array.<Integer> + + + + An array of (binary) integers to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ The string representation of the array +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> calc_checksum(text) → {Integer}

+ + +
+
+ + +
+ Calculates a 16bit sum of a string by adding each character +codes modulus 65535 +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
text + + +String + + + + String to create a sum of
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ An integer containing the sum of all character +codes % 65535 +
+ + + +
+
+ Type +
+
+ +Integer + + +
+
+ + + + +
+ + + +
+

<static> decode_utf8(utf8) → {String}

+ + +
+
+ + +
+ Convert a string of utf8 bytes to a native javascript string +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
utf8 + + +String + + + + A valid squence of utf8 bytes
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A native javascript string +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> encode_utf8(str) → {String}

+ + +
+
+ + +
+ Convert a native javascript string to a string of utf8 bytes +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + The string to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ A valid squence of utf8 bytes +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> get_hashAlgorithmString() → {String}

+ + +
+
+ + +
+ Return the algorithm type as string +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ String representing the message type +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> hex2bin(str) → {String}

+ + +
+
+ + +
+ Create binary string from a hex encoded string +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + Hex string to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ String containing the binary values +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> hexidump(str) → {String}

+ + +
+
+ + +
+ Creating a hex string from an binary array of integers (0..255) +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + Array of bytes to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ Hexadecimal representation of the array +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> hexstrdump(str) → {String}

+ + +
+
+ + +
+ Create hexstring from a binary +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + String to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ String containing the hexadecimal values +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+ + + +
+
+ + +
+ Helper function to print a debug message. Debug +messages are only printed if +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + String of the debug message
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+ + + +
+
+ + +
+ Helper function to print a debug message. Debug +messages are only printed if +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + String of the debug message
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + +
+

<static> shiftRight(value, bitcount) → {String}

+ + +
+
+ + +
+ Shifting a string to n bits right +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +String + + + + The string to shift
bitcount + + +Integer + + + + Amount of bits to shift (MUST be smaller +than 9)
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ Resulting string. +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+ + + +
+

<static> str2bin(str) → {Array.<Integer>}

+ + +
+
+ + +
+ Convert a string to an array of integers(0.255) +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + String to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ An array of (binary) integers +
+ + + +
+
+ Type +
+
+ +Array.<Integer> + + +
+
+ + + + +
+ + + +
+

<static> str2Uint8Array(str) → {Uint8Array}

+ + +
+
+ + +
+ Convert a string to a Uint8Array +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
str + + +String + + + + String to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ The array of (binary) integers +
+ + + +
+
+ Type +
+
+ +Uint8Array + + +
+
+ + + + +
+ + + +
+

<static> Uint8Array2str(bin) → {String}

+ + +
+
+ + +
+ Convert a Uint8Array to a string. This currently functions +the same as bin2str. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
bin + + +Uint8Array + + + + An array of (binary) integers to convert
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ String representation of the array +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + +
+
- - - - - -
@@ -112,13 +2000,13 @@
diff --git a/doc/util.js.html b/doc/util.js.html index 395920ac..1bd92d6c 100644 --- a/doc/util.js.html +++ b/doc/util.js.html @@ -42,20 +42,16 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module util/util */ +/** + * This object contains utility functions + * @requires config + * @module util/util + */ var config = require('../config'); -/** - * - * This object contains utility functions - * - * @class - * @classdesc Implementation of the util object - */ -var Util = function() { - - this.readNumber = function(bytes) { +module.exports = { + readNumber: function (bytes) { var n = 0; for (var i = 0; i < bytes.length; i++) { @@ -64,37 +60,33 @@ var Util = function() { } return n; - }; + }, - this.writeNumber = function(n, bytes) { + writeNumber: function (n, bytes) { var b = ''; for (var i = 0; i < bytes; i++) { - b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); + b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); } return b; - }; + }, - - - this.readDate = function(bytes) { + readDate: function (bytes) { var n = this.readNumber(bytes); var d = new Date(); d.setTime(n * 1000); return d; - }; + }, - this.writeDate = function(time) { + writeDate: function (time) { var numeric = Math.round(time.getTime() / 1000); return this.writeNumber(numeric, 4); - }; + }, - this.emailRegEx = /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/; + emailRegEx: /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/, - this.debug = false; - - this.hexdump = function(str) { + hexdump: function (str) { var r = []; var e = str.length; var c = 0; @@ -109,14 +101,14 @@ var Util = function() { r.push("\n "); } return r.join(''); - }; + }, /** * Create hexstring from a binary * @param {String} str String to convert * @return {String} String containing the hexadecimal values */ - this.hexstrdump = function(str) { + hexstrdump: function (str) { if (str == null) return ""; var r = []; @@ -129,26 +121,26 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** * Create binary string from a hex encoded string * @param {String} str Hex string to convert * @return {String} String containing the binary values */ - this.hex2bin = function(hex) { + hex2bin: function (hex) { var str = ''; for (var i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); return str; - }; + }, /** * Creating a hex string from an binary array of integers (0..255) * @param {String} str Array of bytes to convert * @return {String} Hexadecimal representation of the array */ - this.hexidump = function(str) { + hexidump: function (str) { var r = []; var e = str.length; var c = 0; @@ -159,7 +151,7 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** @@ -167,32 +159,29 @@ var Util = function() { * @param {String} str The string to convert * @return {String} A valid squence of utf8 bytes */ - this.encode_utf8 = function(str) { + encode_utf8: function (str) { return unescape(encodeURIComponent(str)); - }; + }, /** * Convert a string of utf8 bytes to a native javascript string * @param {String} utf8 A valid squence of utf8 bytes * @return {String} A native javascript string */ - this.decode_utf8 = function(utf8) { + decode_utf8: function (utf8) { try { return decodeURIComponent(escape(utf8)); } catch (e) { return utf8; } - }; + }, - var str2bin = function(str, result) { - for (var i = 0; i < str.length; i++) { - result[i] = str.charCodeAt(i); - } - - return result; - }; - - var bin2str = function(bin) { + /** + * Convert an array of integers(0.255) to a string + * @param {Array<Integer>} bin An array of (binary) integers to convert + * @return {String} The string representation of the array + */ + bin2str: function (bin) { var result = []; for (var i = 0; i < bin.length; i++) { @@ -200,53 +189,57 @@ var Util = function() { } return result.join(''); - }; + }, + + _str2bin: function (str, result) { + for (var i = 0; i < str.length; i++) { + result[i] = str.charCodeAt(i); + } + + return result; + }, /** * Convert a string to an array of integers(0.255) * @param {String} str String to convert * @return {Array<Integer>} An array of (binary) integers */ - this.str2bin = function(str) { - return str2bin(str, new Array(str.length)); - }; + str2bin: function (str) { + return this._str2bin(str, new Array(str.length)); + }, - /** - * Convert an array of integers(0.255) to a string - * @param {Array<Integer>} bin An array of (binary) integers to convert - * @return {String} The string representation of the array - */ - this.bin2str = bin2str; - /** * Convert a string to a Uint8Array * @param {String} str String to convert * @return {Uint8Array} The array of (binary) integers */ - this.str2Uint8Array = function(str) { - return str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); - }; + str2Uint8Array: function (str) { + return this._str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); + }, /** * Convert a Uint8Array to a string. This currently functions - * the same as bin2str. + * the same as bin2str. + * @function module:util/util.Uint8Array2str * @param {Uint8Array} bin An array of (binary) integers to convert * @return {String} String representation of the array */ - this.Uint8Array2str = bin2str; + Uint8Array2str: function (bin) { + return this.bin2str(bin); + }, /** - * Calculates a 16bit sum of a string by adding each character + * Calculates a 16bit sum of a string by adding each character * codes modulus 65535 * @param {String} text String to create a sum of - * @return {Integer} An integer containing the sum of all character + * @return {Integer} An integer containing the sum of all character * codes % 65535 */ - this.calc_checksum = function(text) { + calc_checksum: function (text) { var checksum = { s: 0, - add: function(sadd) { + add: function (sadd) { this.s = (this.s + sadd) % 65536; } }; @@ -254,42 +247,42 @@ var Util = function() { checksum.add(text.charCodeAt(i)); } return checksum.s; - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * @param {String} str String of the debug message */ - this.print_debug = function(str) { + print_debug: function (str) { if (config.debug) { console.log(str); } - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * Different than print_debug because will call hexstrdump iff necessary. * @param {String} str String of the debug message */ - this.print_debug_hexstr_dump = function(str, strToHex) { + print_debug_hexstr_dump: function (str, strToHex) { if (config.debug) { str = str + this.hexstrdump(strToHex); console.log(str); } - }; + }, - this.getLeftNBits = function(string, bitcount) { + getLeftNBits: function (string, bitcount) { var rest = bitcount % 8; if (rest == 0) return string.substring(0, bitcount / 8); var bytes = (bitcount - rest) / 8 + 1; var result = string.substring(0, bytes); - return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; + return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); + }, /** * Shifting a string to n bits right @@ -298,25 +291,25 @@ var Util = function() { * than 9) * @return {String} Resulting string. */ - this.shiftRight = function(value, bitcount) { + shiftRight: function (value, bitcount) { var temp = util.str2bin(value); if (bitcount % 8 != 0) { for (var i = temp.length - 1; i >= 0; i--) { temp[i] >>= bitcount % 8; if (i > 0) - temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; + temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; } } else { return value; } return util.bin2str(temp); - }; + }, /** * Return the algorithm type as string * @return {String} String representing the message type */ - this.get_hashAlgorithmString = function(algo) { + get_hashAlgorithmString: function (algo) { switch (algo) { case 1: return "MD5"; @@ -334,15 +327,8 @@ var Util = function() { return "SHA224"; } return "unknown"; - }; - + } }; - -/** - * an instance that should be used. - */ - -module.exports = new Util(); @@ -353,13 +339,13 @@ module.exports = new Util();
diff --git a/jsdoc.template/README.md b/jsdoc.template/README.md new file mode 100644 index 00000000..a7bd96bf --- /dev/null +++ b/jsdoc.template/README.md @@ -0,0 +1 @@ +The default template for JSDoc 3 uses: [the Taffy Database library](http://taffydb.com/) and the [Underscore Template library](http://documentcloud.github.com/underscore/#template). diff --git a/jsdoc.template/publish.js b/jsdoc.template/publish.js new file mode 100644 index 00000000..ad23b506 --- /dev/null +++ b/jsdoc.template/publish.js @@ -0,0 +1,565 @@ +/*global env: true */ +var template = require('jsdoc/template'), + fs = require('jsdoc/fs'), + path = require('jsdoc/path'), + taffy = require('taffydb').taffy, + handle = require('jsdoc/util/error').handle, + helper = require('jsdoc/util/templateHelper'), + htmlsafe = helper.htmlsafe, + linkto = helper.linkto, + resolveAuthorLinks = helper.resolveAuthorLinks, + scopeToPunc = helper.scopeToPunc, + hasOwnProp = Object.prototype.hasOwnProperty, + data, + view, + outdir = env.opts.destination; + + +function find(spec) { + return helper.find(data, spec); +} + +function tutoriallink(tutorial) { + return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' }); +} + +function getAncestorLinks(doclet) { + return helper.getAncestorLinks(data, doclet); +} + +function hashToLink(doclet, hash) { + if ( !/^(#.+)/.test(hash) ) { return hash; } + + var url = helper.createLink(doclet); + + url = url.replace(/(#.+|$)/, hash); + return '' + hash + ''; +} + +function needsSignature(doclet) { + var needsSig = false; + + // function and class definitions always get a signature + if (doclet.kind === 'function' || doclet.kind === 'class') { + needsSig = true; + } + // typedefs that contain functions get a signature, too + else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names && + doclet.type.names.length) { + for (var i = 0, l = doclet.type.names.length; i < l; i++) { + if (doclet.type.names[i].toLowerCase() === 'function') { + needsSig = true; + break; + } + } + } + + return needsSig; +} + +function addSignatureParams(f) { + var params = helper.getSignatureParams(f, 'optional'); + + f.signature = (f.signature || '') + '('+params.join(', ')+')'; +} + +function addSignatureReturns(f) { + var returnTypes = helper.getSignatureReturns(f); + + f.signature = ''+(f.signature || '') + '' + ''+(returnTypes.length? ' → {'+returnTypes.join('|')+'}' : '')+''; +} + +function addSignatureTypes(f) { + var types = helper.getSignatureTypes(f); + + f.signature = (f.signature || '') + ''+(types.length? ' :'+types.join('|') : '')+''; +} + +function addAttribs(f) { + var attribs = helper.getAttribs(f); + + f.attribs = ''+htmlsafe(attribs.length? '<'+attribs.join(', ')+'> ' : '')+''; +} + +function shortenPaths(files, commonPrefix) { + // always use forward slashes + var regexp = new RegExp('\\\\', 'g'); + + Object.keys(files).forEach(function(file) { + files[file].shortened = files[file].resolved.replace(commonPrefix, '') + .replace(regexp, '/'); + }); + + return files; +} + +function resolveSourcePath(filepath) { + return path.resolve(process.cwd(), filepath); +} + +function getPathFromDoclet(doclet) { + if (!doclet.meta) { + return; + } + + var filepath = doclet.meta.path && doclet.meta.path !== 'null' ? + doclet.meta.path + '/' + doclet.meta.filename : + doclet.meta.filename; + + return filepath; +} + +function generate(title, docs, filename, resolveLinks) { + resolveLinks = resolveLinks === false ? false : true; + + var docData = { + title: title, + docs: docs + }; + + var outpath = path.join(outdir, filename), + html = view.render('container.tmpl', docData); + + if (resolveLinks) { + html = helper.resolveLinks(html); // turn {@link foo} into foo + } + + fs.writeFileSync(outpath, html, 'utf8'); +} + +function generateSourceFiles(sourceFiles) { + Object.keys(sourceFiles).forEach(function(file) { + var source; + // links are keyed to the shortened path in each doclet's `meta.filename` property + var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened); + helper.registerLink(sourceFiles[file].shortened, sourceOutfile); + + try { + source = { + kind: 'source', + code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, 'utf8') ) + }; + } + catch(e) { + handle(e); + } + + generate('Source: ' + sourceFiles[file].shortened, [source], sourceOutfile, + false); + }); +} + +/** + * Look for classes or functions with the same name as modules (which indicates that the module + * exports only that class or function), then attach the classes or functions to the `module` + * property of the appropriate module doclets. The name of each class or function is also updated + * for display purposes. This function mutates the original arrays. + * + * @private + * @param {Array.} doclets - The array of classes and functions to + * check. + * @param {Array.} modules - The array of module doclets to search. + */ +function attachModuleSymbols(doclets, modules) { + var symbols = {}; + + // build a lookup table + doclets.forEach(function(symbol) { + symbols[symbol.longname] = symbol; + }); + + return modules.map(function(module) { + if (symbols[module.longname]) { + module.module = symbols[module.longname]; + if (module.module.kind == 'class') { + module.module.name = module.module.name.replace('module:', '(require("') + '"))'; + } else { + module.module.name = module.module.name.replace('module:', 'require("') + '")'; + } + } + }); +} + +/** + * Create the navigation sidebar. + * @param {object} members The members that will be used to create the sidebar. + * @param {array} members.classes + * @param {array} members.externals + * @param {array} members.globals + * @param {array} members.mixins + * @param {array} members.modules + * @param {array} members.namespaces + * @param {array} members.tutorials + * @param {array} members.events + * @return {string} The HTML for the navigation sidebar. + */ +function buildNav(members) { + var nav = '

Index

', + seen = {}, + hasClassList = false, + classNav = '', + globalNav = ''; + + if (members.modules.length) { + nav += '

Modules

    '; + members.modules.forEach(function(m) { + if ( !hasOwnProp.call(seen, m.longname) ) { + nav += '
  • '+linkto(m.longname, m.name)+'
  • '; + } + seen[m.longname] = true; + }); + + nav += '
'; + } + + if (members.externals.length) { + nav += '

Externals

    '; + members.externals.forEach(function(e) { + if ( !hasOwnProp.call(seen, e.longname) ) { + nav += '
  • '+linkto( e.longname, e.name.replace(/(^"|"$)/g, '') )+'
  • '; + } + seen[e.longname] = true; + }); + + nav += '
'; + } + + if (members.classes.length) { + members.classes.forEach(function(c) { + if ( !hasOwnProp.call(seen, c.longname) ) { + classNav += '
  • '+linkto(c.longname, c.name)+'
  • '; + } + seen[c.longname] = true; + }); + + if (classNav !== '') { + nav += '

    Classes

      '; + nav += classNav; + nav += '
    '; + } + } + + if (members.events.length) { + nav += '

    Events

      '; + members.events.forEach(function(e) { + if ( !hasOwnProp.call(seen, e.longname) ) { + nav += '
    • '+linkto(e.longname, e.name)+'
    • '; + } + seen[e.longname] = true; + }); + + nav += '
    '; + } + + if (members.namespaces.length) { + nav += '

    Namespaces

      '; + members.namespaces.forEach(function(n) { + if ( !hasOwnProp.call(seen, n.longname) ) { + nav += '
    • '+linkto(n.longname, n.name)+'
    • '; + } + seen[n.longname] = true; + }); + + nav += '
    '; + } + + if (members.mixins.length) { + nav += '

    Mixins

      '; + members.mixins.forEach(function(m) { + if ( !hasOwnProp.call(seen, m.longname) ) { + nav += '
    • '+linkto(m.longname, m.name)+'
    • '; + } + seen[m.longname] = true; + }); + + nav += '
    '; + } + + if (members.tutorials.length) { + nav += '

    Tutorials

      '; + members.tutorials.forEach(function(t) { + nav += '
    • '+tutoriallink(t.name)+'
    • '; + }); + + nav += '
    '; + } + + if (members.globals.length) { + members.globals.forEach(function(g) { + if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) { + globalNav += '
  • ' + linkto(g.longname, g.name) + '
  • '; + } + seen[g.longname] = true; + }); + + if (!globalNav) { + // turn the heading into a link so you can actually get to the global page + nav += '

    ' + linkto('global', 'Global') + '

    '; + } + else { + nav += '

    Global

      ' + globalNav + '
    '; + } + } + + return nav; +} + + +/** + @param {TAFFY} taffyData See . + @param {object} opts + @param {Tutorial} tutorials + */ +exports.publish = function(taffyData, opts, tutorials) { + data = taffyData; + + var conf = env.conf.templates || {}; + conf['default'] = conf['default'] || {}; + + var templatePath = opts.template; + view = new template.Template(templatePath + '/tmpl'); + + // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness + // doesn't try to hand them out later + var indexUrl = helper.getUniqueFilename('index'); + // don't call registerLink() on this one! 'index' is also a valid longname + + var globalUrl = helper.getUniqueFilename('global'); + helper.registerLink('global', globalUrl); + + // set up templating + view.layout = 'layout.tmpl'; + + // set up tutorials for helper + helper.setTutorials(tutorials); + + data = helper.prune(data); + data.sort('longname, version, since'); + helper.addEventListeners(data); + + var sourceFiles = {}; + var sourceFilePaths = []; + data().each(function(doclet) { + doclet.attribs = ''; + + if (doclet.examples) { + doclet.examples = doclet.examples.map(function(example) { + var caption, code; + + if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) { + caption = RegExp.$1; + code = RegExp.$3; + } + + return { + caption: caption || '', + code: code || example + }; + }); + } + if (doclet.see) { + doclet.see.forEach(function(seeItem, i) { + doclet.see[i] = hashToLink(doclet, seeItem); + }); + } + + // build a list of source files + var sourcePath; + var resolvedSourcePath; + if (doclet.meta) { + sourcePath = getPathFromDoclet(doclet); + resolvedSourcePath = resolveSourcePath(sourcePath); + sourceFiles[sourcePath] = { + resolved: resolvedSourcePath, + shortened: null + }; + sourceFilePaths.push(resolvedSourcePath); + } + }); + + // update outdir if necessary, then create outdir + var packageInfo = ( find({kind: 'package'}) || [] ) [0]; + if (packageInfo && packageInfo.name) { + outdir = path.join(outdir, packageInfo.name, packageInfo.version); + } + fs.mkPath(outdir); + + // copy the template's static files to outdir + var fromDir = path.join(templatePath, 'static'); + var staticFiles = fs.ls(fromDir, 3); + + staticFiles.forEach(function(fileName) { + var toDir = fs.toDir( fileName.replace(fromDir, outdir) ); + fs.mkPath(toDir); + fs.copyFileSync(fileName, toDir); + }); + + // copy user-specified static files to outdir + var staticFilePaths; + var staticFileFilter; + var staticFileScanner; + if (conf['default'].staticFiles) { + staticFilePaths = conf['default'].staticFiles.paths || []; + staticFileFilter = new (require('jsdoc/src/filter')).Filter(conf['default'].staticFiles); + staticFileScanner = new (require('jsdoc/src/scanner')).Scanner(); + + staticFilePaths.forEach(function(filePath) { + var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter); + + extraStaticFiles.forEach(function(fileName) { + var sourcePath = fs.statSync(filePath).isDirectory() ? filePath : + path.dirname(filePath); + var toDir = fs.toDir( fileName.replace(sourcePath, outdir) ); + fs.mkPath(toDir); + fs.copyFileSync(fileName, toDir); + }); + }); + } + + if (sourceFilePaths.length) { + sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) ); + } + data().each(function(doclet) { + var url = helper.createLink(doclet); + helper.registerLink(doclet.longname, url); + + // replace the filename with a shortened version of the full path + var docletPath; + if (doclet.meta) { + docletPath = getPathFromDoclet(doclet); + docletPath = sourceFiles[docletPath].shortened; + if (docletPath) { + doclet.meta.filename = docletPath; + } + } + }); + + data().each(function(doclet) { + var url = helper.longnameToUrl[doclet.longname]; + + if (url.indexOf('#') > -1) { + doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop(); + } + else { + doclet.id = doclet.name; + } + + if ( needsSignature(doclet) ) { + addSignatureParams(doclet); + addSignatureReturns(doclet); + addAttribs(doclet); + } + }); + + // do this after the urls have all been generated + data().each(function(doclet) { + doclet.ancestors = getAncestorLinks(doclet); + + if (doclet.kind === 'member') { + addSignatureTypes(doclet); + addAttribs(doclet); + } + + if (doclet.kind === 'constant') { + addSignatureTypes(doclet); + addAttribs(doclet); + doclet.kind = 'member'; + } + }); + + var members = helper.getMembers(data); + members.tutorials = tutorials.children; + + // add template helpers + view.find = find; + view.linkto = linkto; + view.resolveAuthorLinks = resolveAuthorLinks; + view.tutoriallink = tutoriallink; + view.htmlsafe = htmlsafe; + + // once for all + view.nav = buildNav(members); + attachModuleSymbols( find({ kind: ['class', 'function'], longname: {left: 'module:'} }), + members.modules ); + + // only output pretty-printed source files if requested; do this before generating any other + // pages, so the other pages can link to the source files + if (conf['default'].outputSourceFiles) { + generateSourceFiles(sourceFiles); + } + + if (members.globals.length) { generate('Global', [{kind: 'globalobj'}], globalUrl); } + + // index page displays information from package.json and lists files + var files = find({kind: 'file'}), + packages = find({kind: 'package'}); + + generate('Index', + packages.concat( + [{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}] + ).concat(files), + indexUrl); + + // set up the lists that we'll use to generate pages + var classes = taffy(members.classes); + var modules = taffy(members.modules); + var namespaces = taffy(members.namespaces); + var mixins = taffy(members.mixins); + var externals = taffy(members.externals); + + for (var longname in helper.longnameToUrl) { + if ( hasOwnProp.call(helper.longnameToUrl, longname) ) { + var myClasses = helper.find(classes, {longname: longname}); + if (myClasses.length) { + generate('Class: ' + myClasses[0].name, myClasses, helper.longnameToUrl[longname]); + } + + var myModules = helper.find(modules, {longname: longname}); + if (myModules.length) { + generate('Module: ' + myModules[0].name, myModules, helper.longnameToUrl[longname]); + } + + var myNamespaces = helper.find(namespaces, {longname: longname}); + if (myNamespaces.length) { + generate('Namespace: ' + myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]); + } + + var myMixins = helper.find(mixins, {longname: longname}); + if (myMixins.length) { + generate('Mixin: ' + myMixins[0].name, myMixins, helper.longnameToUrl[longname]); + } + + var myExternals = helper.find(externals, {longname: longname}); + if (myExternals.length) { + generate('External: ' + myExternals[0].name, myExternals, helper.longnameToUrl[longname]); + } + } + } + + // TODO: move the tutorial functions to templateHelper.js + function generateTutorial(title, tutorial, filename) { + var tutorialData = { + title: title, + header: tutorial.title, + content: tutorial.parse(), + children: tutorial.children + }; + + var tutorialPath = path.join(outdir, filename), + html = view.render('tutorial.tmpl', tutorialData); + + // yes, you can use {@link} in tutorials too! + html = helper.resolveLinks(html); // turn {@link foo} into foo + + fs.writeFileSync(tutorialPath, html, 'utf8'); + } + + // tutorials can have only one parent so there is no risk for loops + function saveChildren(node) { + node.children.forEach(function(child) { + generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name)); + saveChildren(child); + }); + } + saveChildren(tutorials); +}; diff --git a/jsdoc.template/static/scripts/linenumber.js b/jsdoc.template/static/scripts/linenumber.js new file mode 100644 index 00000000..a0c570d5 --- /dev/null +++ b/jsdoc.template/static/scripts/linenumber.js @@ -0,0 +1,17 @@ +(function() { + var counter = 0; + var numbered; + var source = document.getElementsByClassName('prettyprint source'); + + if (source && source[0]) { + source = source[0].getElementsByTagName('code')[0]; + + numbered = source.innerHTML.split('\n'); + numbered = numbered.map(function(item) { + counter++; + return '' + item; + }); + + source.innerHTML = numbered.join('\n'); + } +})(); diff --git a/jsdoc.template/static/scripts/prettify/Apache-License-2.0.txt b/jsdoc.template/static/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/jsdoc.template/static/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/jsdoc.template/static/scripts/prettify/lang-css.js b/jsdoc.template/static/scripts/prettify/lang-css.js new file mode 100644 index 00000000..041e1f59 --- /dev/null +++ b/jsdoc.template/static/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/jsdoc.template/static/scripts/prettify/prettify.js b/jsdoc.template/static/scripts/prettify/prettify.js new file mode 100644 index 00000000..eef5ad7e --- /dev/null +++ b/jsdoc.template/static/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p + + + + + + + +
    + +
    +

    + + + + + +

    + +
    + +
    + +
    +
    + + +
    + + + + + + + + +
    + + + + + +

    Example 1? 's':'' ?>

    + + + +
    + + +

    Extends

    + +
      +
    • +
    + + + +

    Mixes In

    + +
      +
    • +
    + + + +

    Requires

    + +
      +
    • +
    + + + +

    Classes

    + +
    +
    +
    +
    + + + +

    Namespaces

    + +
    +
    +
    +
    + + + +

    Members

    + +
    + +
    + + + +

    Methods

    + +
    + +
    + + + +

    Type Definitions

    + +
    + + + +
    + + + +

    Events

    + +
    + +
    + +
    + +
    + + + diff --git a/jsdoc.template/tmpl/details.tmpl b/jsdoc.template/tmpl/details.tmpl new file mode 100644 index 00000000..d3b35522 --- /dev/null +++ b/jsdoc.template/tmpl/details.tmpl @@ -0,0 +1,98 @@ + +
    + + +
    Properties:
    + +
    + + + + +
    Version:
    +
    + + + +
    Since:
    +
    + + + +
    Inherited From:
    +
    • + +
    + + + +
    Deprecated:
    • Yes
      + + + +
      Author:
      +
      +
        +
      • +
      +
      + + + + + + + + +
      License:
      +
      + + + +
      Default Value:
      +
      + + + +
      Source:
      +
      • + , +
      + + + +
      Tutorials:
      +
      +
        +
      • +
      +
      + + + +
      See:
      +
      +
        +
      • +
      +
      + + + +
      To Do:
      +
      +
        +
      • +
      +
      + +
      diff --git a/jsdoc.template/tmpl/example.tmpl b/jsdoc.template/tmpl/example.tmpl new file mode 100644 index 00000000..e87caa5b --- /dev/null +++ b/jsdoc.template/tmpl/example.tmpl @@ -0,0 +1,2 @@ + +
      diff --git a/jsdoc.template/tmpl/examples.tmpl b/jsdoc.template/tmpl/examples.tmpl new file mode 100644 index 00000000..23384c9d --- /dev/null +++ b/jsdoc.template/tmpl/examples.tmpl @@ -0,0 +1,11 @@ + +

      + +
      + \ No newline at end of file diff --git a/jsdoc.template/tmpl/exceptions.tmpl b/jsdoc.template/tmpl/exceptions.tmpl new file mode 100644 index 00000000..78c4e250 --- /dev/null +++ b/jsdoc.template/tmpl/exceptions.tmpl @@ -0,0 +1,30 @@ + + +
      +
      +
      + +
      +
      +
      +
      +
      + Type +
      +
      + +
      +
      +
      +
      + +
      + + + + + +
      + diff --git a/jsdoc.template/tmpl/layout.tmpl b/jsdoc.template/tmpl/layout.tmpl new file mode 100644 index 00000000..827b5acb --- /dev/null +++ b/jsdoc.template/tmpl/layout.tmpl @@ -0,0 +1,38 @@ + + + + + JSDoc: <?js= title ?> + + + + + + + + + + +
      + +

      + + +
      + + + +
      + +
      + Documentation generated by JSDoc on +
      + + + + + diff --git a/jsdoc.template/tmpl/mainpage.tmpl b/jsdoc.template/tmpl/mainpage.tmpl new file mode 100644 index 00000000..64e9e594 --- /dev/null +++ b/jsdoc.template/tmpl/mainpage.tmpl @@ -0,0 +1,14 @@ + + + +

      + + + +
      +
      +
      + diff --git a/jsdoc.template/tmpl/members.tmpl b/jsdoc.template/tmpl/members.tmpl new file mode 100644 index 00000000..3fded716 --- /dev/null +++ b/jsdoc.template/tmpl/members.tmpl @@ -0,0 +1,34 @@ + +
      +

      + + +

      + +
      +
      + +
      + +
      + + + +
      Type:
      +
        +
      • + +
      • +
      + + + + + +
      Example 1? 's':'' ?>
      + + +
      diff --git a/jsdoc.template/tmpl/method.tmpl b/jsdoc.template/tmpl/method.tmpl new file mode 100644 index 00000000..1fff9b86 --- /dev/null +++ b/jsdoc.template/tmpl/method.tmpl @@ -0,0 +1,90 @@ + +
      +

      + + +

      + +
      +
      + + +
      + +
      + + + +
      Type:
      +
        +
      • + +
      • +
      + + + +
      This:
      +
      + + + +
      Parameters:
      + + + + + + +
      Fires:
      +
        +
      • +
      + + + +
      Listens to Events:
      +
        +
      • +
      + + + +
      Listeners of This Event:
      +
        +
      • +
      + + + +
      Throws:
      + 1) { ?>
        +
      • +
      + + + + +
      Returns:
      + 1) { ?>
        +
      • +
      + + + + +
      Example 1? 's':'' ?>
      + + +
      diff --git a/jsdoc.template/tmpl/params.tmpl b/jsdoc.template/tmpl/params.tmpl new file mode 100644 index 00000000..7b951149 --- /dev/null +++ b/jsdoc.template/tmpl/params.tmpl @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeArgumentDefaultDescription
      + + + + + + <optional>
      + + + + <nullable>
      + + + + <repeatable>
      + +
      + + + + +
      Properties
      + +
      \ No newline at end of file diff --git a/jsdoc.template/tmpl/properties.tmpl b/jsdoc.template/tmpl/properties.tmpl new file mode 100644 index 00000000..97a3d23a --- /dev/null +++ b/jsdoc.template/tmpl/properties.tmpl @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeArgumentDefaultDescription
      + + + + + + <optional>
      + + + + <nullable>
      + +
      + + + + +
      Properties
      +
      \ No newline at end of file diff --git a/jsdoc.template/tmpl/returns.tmpl b/jsdoc.template/tmpl/returns.tmpl new file mode 100644 index 00000000..32e059ed --- /dev/null +++ b/jsdoc.template/tmpl/returns.tmpl @@ -0,0 +1,19 @@ + +
      + +
      + + + +
      +
      + Type +
      +
      + +
      +
      + \ No newline at end of file diff --git a/jsdoc.template/tmpl/source.tmpl b/jsdoc.template/tmpl/source.tmpl new file mode 100644 index 00000000..e1092ef2 --- /dev/null +++ b/jsdoc.template/tmpl/source.tmpl @@ -0,0 +1,8 @@ + +
      +
      +
      +
      +
      \ No newline at end of file diff --git a/jsdoc.template/tmpl/tutorial.tmpl b/jsdoc.template/tmpl/tutorial.tmpl new file mode 100644 index 00000000..b0c79c1d --- /dev/null +++ b/jsdoc.template/tmpl/tutorial.tmpl @@ -0,0 +1,19 @@ +
      + +
      + 0) { ?> +
        +
      • +
      + + +

      +
      + +
      + +
      + +
      diff --git a/jsdoc.template/tmpl/type.tmpl b/jsdoc.template/tmpl/type.tmpl new file mode 100644 index 00000000..db8194d6 --- /dev/null +++ b/jsdoc.template/tmpl/type.tmpl @@ -0,0 +1,7 @@ + + +| + \ No newline at end of file diff --git a/package.json b/package.json index eb2c951a..ba2fe493 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "grunt-text-replace": "*", "grunt-jsbeautifier": "*", "grunt-contrib-jshint": "*", - "grunt-jsdoc": "*", - "jsdoc": "~3.3.0-alpha2" + "grunt-jsdoc": "*" } } diff --git a/resources/keyring.js b/resources/keyring.js index b154c69f..4208e1fd 100644 --- a/resources/keyring.js +++ b/resources/keyring.js @@ -23,36 +23,55 @@ module.exports=require('fjvtDg'); // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/keyring */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/keyring + */ var openpgp = require('openpgp'); /** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * Callback to check if a key matches the input + * @callback module:keyring/keyring.checkCallback + * @param {String} input input to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the input matches the specified key */ -module.exports = function() { - this.keys = []; + +/** + * Initialization routine for the keyring. This method reads the + * keyring from HTML5 local storage and initializes this instance. + * @constructor + * @param {class} [storeHandler] class implementing load() and store() methods + */ +module.exports = function(storeHandler) { + if (!storeHandler) { + storeHandler = new (require('./localstore.js'))(); + } + this.storeHandler = storeHandler; + this.keys = this.storeHandler.load(); /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Calls the storeHandler to save the keys */ - this.init = function (storeHandler) { - if (!storeHandler) { - var localstore = require('./localstore.js'); - storeHandler = new localstore(); - } - this.storeHandler = storeHandler; - this.keys = []; - this.storeHandler.init(this.keys); - } - this.store = function () { this.storeHandler.store(this.keys); - } + }; + /** + * Clear the keyring - erase all the keys + */ + this.clear = function() { + this.keys = []; + }; + + /** + * Checks a key to see if it matches the specified email address + * @param {String} email email address to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the email address is defined in the specified key + */ function emailCheck(email, key) { email = email.toLowerCase(); var keyEmails = key.getUserIds(); @@ -66,6 +85,13 @@ module.exports = function() { return false; } + /** + * Checks a key to see if it matches the specified keyid + * @param {String} id hex string keyid to search for + * @param {module:key~Key} key the key to be checked. + * @return {Boolean} true if the email address is defined in the specified key + * @inner + */ function idCheck(id, key) { var keyids = key.getKeyIds(); for (var i = 0; i < keyids.length; i++) { @@ -76,6 +102,14 @@ module.exports = function() { return false; } + /** + * searches all public keys in the keyring matching the address or address part of the user ids + * @param {Array} keys array of keys to search + * @param {module:keyring/keyring.checkCallback} identityFunction callback function which checks for a match + * @param {String} identityInput input to check against + * @param {module:enums.packet} keyType packet types of keys to check + * @return {Array} array of keys which match + */ function checkForIdentityAndKeyTypeMatch(keys, identityFunction, identityInput, keyType) { var results = []; for (var p = 0; p < keys.length; p++) { @@ -95,7 +129,6 @@ module.exports = function() { } return results; } - this.checkForIdentityAndKeyTypeMatch = checkForIdentityAndKeyTypeMatch; /** * searches all public keys in the keyring matching the address or address part of the user ids @@ -104,71 +137,64 @@ module.exports = function() { */ this.getPublicKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.public_key); - } + }; /** * Searches the keyring for a private key containing the specified email address * @param {String} email email address to search for * @return {Array} private keys found */ - function getPrivateKeyForAddress(email) { + this.getPrivateKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.secret_key); - } - this.getPrivateKeyForAddress = getPrivateKeyForAddress; + }; /** * Searches the keyring for public keys having the specified key id * @param {String} keyId provided as string of hex number (lowercase) * @return {Array} public keys found */ - function getKeysForKeyId(keyId) { - return this.checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); - } - this.getKeysForKeyId = getKeysForKeyId; + this.getKeysForKeyId = function (keyId) { + return checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); + }; /** * Imports a key from an ascii armored message * @param {String} armored message to read the keys/key from */ - function importKey(armored) { + this.importKey = function (armored) { this.keys = this.keys.concat(openpgp.key.readArmored(armored).keys); return true; - } - this.importKey = importKey; + }; /** * returns the armored message representation of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the key object */ - function exportKey(index) { + this.exportKey = function (index) { return this.keys[index].armor(); - } - this.exportKey = exportKey; + }; /** - * Removes a public key from the public key keyring at the specified index + * Removes a public key from the public key keyring at the specified index * @param {Integer} index the index of the public key within the publicKeys array * @return {module:key~Key} The public key object which has been removed */ - function removeKey(index) { + this.removeKey = function (index) { var removed = this.keys.splice(index, 1); return removed; - } - this.removeKey = removeKey; + }; /** * returns the armored message representation of the public key portion of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the public key object */ - function exportPublicKey(index) { + this.exportPublicKey = function (index) { return this.keys[index].toPublic().armor(); - } - this.exportPublicKey = exportPublicKey; - + }; }; },{"./localstore.js":4}],4:[function(require,module,exports){ @@ -189,36 +215,36 @@ module.exports = function() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/localstore */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/localstore + */ var openpgp = require('openpgp'); -/** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. - */ module.exports = function () { /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Load the keyring from HTML5 local storage and initializes this instance. + * @return {Array} array of keys retrieved from localstore */ - this.init = function (keys) { + this.load = function () { var armoredKeys = JSON.parse(window.localStorage.getItem("armoredKeys")); - if (armoredKeys !== null && armoredKeys.length === 0) { + var keys = []; + if (armoredKeys !== null && armoredKeys.length !== 0) { var key; for (var i = 0; i < armoredKeys.length; i++) { key = openpgp.key.readArmored(armoredKeys[i]); keys.push(key); } - } else { - this.keys = []; } + return keys; } /** * Saves the current state of the keyring to HTML5 local storage. * The privateKeys array and publicKeys array gets Stringified using JSON + * @param {Array} keys array of keys to save in localstore */ this.store = function (keys) { var armoredKeys = []; @@ -230,5 +256,5 @@ module.exports = function () { }; },{}]},{},[]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleXJpbmcvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleXJpbmcva2V5cmluZy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMva2V5cmluZy9sb2NhbHN0b3JlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4va2V5cmluZy5qcycpO1xubW9kdWxlLmV4cG9ydHMubG9jYWxzdG9yZSA9IHJlcXVpcmUoJy4vbG9jYWxzdG9yZS5qcycpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUga2V5cmluZy9rZXlyaW5nICovXG5cbnZhciBvcGVucGdwID0gcmVxdWlyZSgnb3BlbnBncCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBUaGUgY2xhc3MgdGhhdCBkZWFscyB3aXRoIHN0b3JhZ2Ugb2YgdGhlIGtleXJpbmcuIEN1cnJlbnRseSB0aGUgb25seSBvcHRpb24gaXMgdG8gdXNlIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMua2V5cyA9IFtdO1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXphdGlvbiByb3V0aW5lIGZvciB0aGUga2V5cmluZy4gVGhpcyBtZXRob2QgcmVhZHMgdGhlIFxuICAgKiBrZXlyaW5nIGZyb20gSFRNTDUgbG9jYWwgc3RvcmFnZSBhbmQgaW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZS5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IG9wZW5wZ3AuaW5pdCgpLlxuICAgKi9cbiAgdGhpcy5pbml0ID0gZnVuY3Rpb24gKHN0b3JlSGFuZGxlcikge1xuICAgIGlmICghc3RvcmVIYW5kbGVyKSB7XG4gICAgICB2YXIgbG9jYWxzdG9yZSA9IHJlcXVpcmUoJy4vbG9jYWxzdG9yZS5qcycpO1xuICAgICAgc3RvcmVIYW5kbGVyID0gbmV3IGxvY2Fsc3RvcmUoKTtcbiAgICB9XG4gICAgdGhpcy5zdG9yZUhhbmRsZXIgPSBzdG9yZUhhbmRsZXI7XG4gICAgdGhpcy5rZXlzID0gW107XG4gICAgdGhpcy5zdG9yZUhhbmRsZXIuaW5pdCh0aGlzLmtleXMpO1xuICB9XG5cbiAgdGhpcy5zdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnN0b3JlSGFuZGxlci5zdG9yZSh0aGlzLmtleXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW1haWxDaGVjayhlbWFpbCwga2V5KSB7XG4gICAgZW1haWwgPSBlbWFpbC50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBrZXlFbWFpbHMgPSBrZXkuZ2V0VXNlcklkcygpO1xuICAgIGZvciAodmFyIGk7IGkgPCBrZXlFbWFpbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vd2UgbmVlZCB0byBnZXQganVzdCB0aGUgZW1haWwgZnJvbSB0aGUgdXNlcmlkIGtleVxuICAgICAga2V5RW1haWwgPSBrZXlFbWFpbHNbaV0uc3BsaXQoJzwnKVsxXS5zcGxpdCgnPicpWzBdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGtleUVtYWlsID09IGVtYWlsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBpZENoZWNrKGlkLCBrZXkpIHtcbiAgICB2YXIga2V5aWRzID0ga2V5LmdldEtleUlkcygpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5aWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAob3BlbnBncC51dGlsLmhleHN0cmR1bXAoa2V5aWRzW2ldLndyaXRlKCkpID09IGlkKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBjaGVja0ZvcklkZW50aXR5QW5kS2V5VHlwZU1hdGNoKGtleXMsIGlkZW50aXR5RnVuY3Rpb24sIGlkZW50aXR5SW5wdXQsIGtleVR5cGUpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGZvciAodmFyIHAgPSAwOyBwIDwga2V5cy5sZW5ndGg7IHArKykge1xuICAgICAgdmFyIGtleSA9IGtleXNbcF07XG4gICAgICBzd2l0Y2ggKGtleVR5cGUpIHtcbiAgICAgICAgY2FzZSBvcGVucGdwLmVudW1zLnBhY2tldC5wdWJsaWNfa2V5OlxuICAgICAgICAgIGlmIChrZXkuaXNQdWJsaWMoKSAmJiBpZGVudGl0eUZ1bmN0aW9uKGlkZW50aXR5SW5wdXQsIGtleSkpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChrZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvcGVucGdwLmVudW1zLnBhY2tldC5wcml2YXRlX2tleTpcbiAgICAgICAgICBpZiAoa2V5LmlzUHJpdmF0ZSgpICYmIGlkZW50aXR5RnVuY3Rpb24oaWRlbnRpdHlJbnB1dCwga2V5KSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGtleSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuICB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRLZXlUeXBlTWF0Y2ggPSBjaGVja0ZvcklkZW50aXR5QW5kS2V5VHlwZU1hdGNoO1xuXG4gIC8qKlxuICAgKiBzZWFyY2hlcyBhbGwgcHVibGljIGtleXMgaW4gdGhlIGtleXJpbmcgbWF0Y2hpbmcgdGhlIGFkZHJlc3Mgb3IgYWRkcmVzcyBwYXJ0IG9mIHRoZSB1c2VyIGlkc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gZW1haWwgZW1haWwgYWRkcmVzcyB0byBzZWFyY2ggZm9yXG4gICAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gVGhlIHB1YmxpYyBrZXlzIGFzc29jaWF0ZWQgd2l0aCBwcm92aWRlZCBlbWFpbCBhZGRyZXNzLlxuICAgKi9cbiAgdGhpcy5nZXRQdWJsaWNLZXlGb3JBZGRyZXNzID0gZnVuY3Rpb24gKGVtYWlsKSB7XG4gICAgcmV0dXJuIGNoZWNrRm9ySWRlbnRpdHlBbmRLZXlUeXBlTWF0Y2godGhpcy5rZXlzLCBlbWFpbENoZWNrLCBlbWFpbCwgb3BlbnBncC5lbnVtcy5wYWNrZXQucHVibGljX2tleSk7XG4gIH1cblxuICAvKipcbiAgICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIGEgcHJpdmF0ZSBrZXkgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVtYWlsIGFkZHJlc3NcbiAgICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsIGVtYWlsIGFkZHJlc3MgdG8gc2VhcmNoIGZvclxuICAgKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHByaXZhdGUga2V5cyBmb3VuZFxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3MoZW1haWwpIHtcbiAgICByZXR1cm4gY2hlY2tGb3JJZGVudGl0eUFuZEtleVR5cGVNYXRjaCh0aGlzLmtleXMsIGVtYWlsQ2hlY2ssIGVtYWlsLCBvcGVucGdwLmVudW1zLnBhY2tldC5zZWNyZXRfa2V5KTtcbiAgfVxuICB0aGlzLmdldFByaXZhdGVLZXlGb3JBZGRyZXNzID0gZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3M7XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIHRoZSBrZXlyaW5nIGZvciBwdWJsaWMga2V5cyBoYXZpbmcgdGhlIHNwZWNpZmllZCBrZXkgaWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleUlkIHByb3ZpZGVkIGFzIHN0cmluZyBvZiBoZXggbnVtYmVyIChsb3dlcmNhc2UpXG4gICAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gcHVibGljIGtleXMgZm91bmRcbiAgICovXG4gIGZ1bmN0aW9uIGdldEtleXNGb3JLZXlJZChrZXlJZCkge1xuICAgIHJldHVybiB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRLZXlUeXBlTWF0Y2godGhpcy5rZXlzLCBpZENoZWNrLCBrZXlJZCwgb3BlbnBncC5lbnVtcy5wYWNrZXQucHVibGljX2tleSk7XG4gIH1cbiAgdGhpcy5nZXRLZXlzRm9yS2V5SWQgPSBnZXRLZXlzRm9yS2V5SWQ7XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgYSBrZXkgZnJvbSBhbiBhc2NpaSBhcm1vcmVkIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWQgbWVzc2FnZSB0byByZWFkIHRoZSBrZXlzL2tleSBmcm9tXG4gICAqL1xuICBmdW5jdGlvbiBpbXBvcnRLZXkoYXJtb3JlZCkge1xuICAgIHRoaXMua2V5cyA9IHRoaXMua2V5cy5jb25jYXQob3BlbnBncC5rZXkucmVhZEFybW9yZWQoYXJtb3JlZCkua2V5cyk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB0aGlzLmltcG9ydEtleSA9IGltcG9ydEtleTtcblxuICAvKipcbiAgICogcmV0dXJucyB0aGUgYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBrZXkgYXQga2V5IHJpbmcgaW5kZXhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGtleSB3aXRoaW4gdGhlIGFycmF5XG4gICAqIEByZXR1cm4ge1N0cmluZ30gYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGluZyB0aGUga2V5IG9iamVjdFxuICAgKi9cbiAgZnVuY3Rpb24gZXhwb3J0S2V5KGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMua2V5c1tpbmRleF0uYXJtb3IoKTtcbiAgfVxuICB0aGlzLmV4cG9ydEtleSA9IGV4cG9ydEtleTtcblxuICAvKipcbiAgICogUmVtb3ZlcyBhIHB1YmxpYyBrZXkgZnJvbSB0aGUgcHVibGljIGtleSBrZXlyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwdWJsaWMga2V5IHdpdGhpbiB0aGUgcHVibGljS2V5cyBhcnJheVxuICAgKiBAcmV0dXJuIHttb2R1bGU6a2V5fktleX0gVGhlIHB1YmxpYyBrZXkgb2JqZWN0IHdoaWNoIGhhcyBiZWVuIHJlbW92ZWRcbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZUtleShpbmRleCkge1xuICAgIHZhciByZW1vdmVkID0gdGhpcy5rZXlzLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICByZXR1cm4gcmVtb3ZlZDtcbiAgfVxuICB0aGlzLnJlbW92ZUtleSA9IHJlbW92ZUtleTtcblxuICAvKipcbiAgICogcmV0dXJucyB0aGUgYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwdWJsaWMga2V5IHBvcnRpb24gb2YgdGhlIGtleSBhdCBrZXkgcmluZyBpbmRleFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IHRoZSBpbmRleCBvZiB0aGUga2V5IHdpdGhpbiB0aGUgYXJyYXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBhcm1vcmVkIG1lc3NhZ2UgcmVwcmVzZW50aW5nIHRoZSBwdWJsaWMga2V5IG9iamVjdFxuICAgKi9cbiAgZnVuY3Rpb24gZXhwb3J0UHVibGljS2V5KGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMua2V5c1tpbmRleF0udG9QdWJsaWMoKS5hcm1vcigpO1xuICB9XG4gIHRoaXMuZXhwb3J0UHVibGljS2V5ID0gZXhwb3J0UHVibGljS2V5O1xuXG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUga2V5cmluZy9sb2NhbHN0b3JlICovXG5cbnZhciBvcGVucGdwID0gcmVxdWlyZSgnb3BlbnBncCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBUaGUgY2xhc3MgdGhhdCBkZWFscyB3aXRoIHN0b3JhZ2Ugb2YgdGhlIGtleXJpbmcuIEN1cnJlbnRseSB0aGUgb25seSBvcHRpb24gaXMgdG8gdXNlIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogSW5pdGlhbGl6YXRpb24gcm91dGluZSBmb3IgdGhlIGtleXJpbmcuIFRoaXMgbWV0aG9kIHJlYWRzIHRoZSBcbiAgICoga2V5cmluZyBmcm9tIEhUTUw1IGxvY2FsIHN0b3JhZ2UgYW5kIGluaXRpYWxpemVzIHRoaXMgaW5zdGFuY2UuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBvcGVucGdwLmluaXQoKS5cbiAgICovXG4gIHRoaXMuaW5pdCA9IGZ1bmN0aW9uIChrZXlzKSB7XG4gICAgdmFyIGFybW9yZWRLZXlzID0gSlNPTi5wYXJzZSh3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJhcm1vcmVkS2V5c1wiKSk7XG4gICAgaWYgKGFybW9yZWRLZXlzICE9PSBudWxsICYmIGFybW9yZWRLZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdmFyIGtleTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJtb3JlZEtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAga2V5ID0gb3BlbnBncC5rZXkucmVhZEFybW9yZWQoYXJtb3JlZEtleXNbaV0pO1xuICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5rZXlzID0gW107XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBrZXlyaW5nIHRvIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gICAqIFRoZSBwcml2YXRlS2V5cyBhcnJheSBhbmQgcHVibGljS2V5cyBhcnJheSBnZXRzIFN0cmluZ2lmaWVkIHVzaW5nIEpTT05cbiAgICovXG4gIHRoaXMuc3RvcmUgPSBmdW5jdGlvbiAoa2V5cykge1xuICAgIHZhciBhcm1vcmVkS2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgYXJtb3JlZEtleXMucHVzaChrZXlzW2ldLmFybW9yKCkpO1xuICAgIH1cbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJhcm1vcmVkS2V5c1wiLCBKU09OLnN0cmluZ2lmeShhcm1vcmVkS2V5cykpO1xuICB9XG59O1xuIl19 +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleXJpbmcvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleXJpbmcva2V5cmluZy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMva2V5cmluZy9sb2NhbHN0b3JlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2tleXJpbmcuanMnKTtcbm1vZHVsZS5leHBvcnRzLmxvY2Fsc3RvcmUgPSByZXF1aXJlKCcuL2xvY2Fsc3RvcmUuanMnKTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogVGhlIGNsYXNzIHRoYXQgZGVhbHMgd2l0aCBzdG9yYWdlIG9mIHRoZSBrZXlyaW5nLiBDdXJyZW50bHkgdGhlIG9ubHkgb3B0aW9uIGlzIHRvIHVzZSBIVE1MNSBsb2NhbCBzdG9yYWdlLlxuICogQHJlcXVpcmVzIG9wZW5wZ3BcbiAqIEBtb2R1bGUga2V5cmluZy9rZXlyaW5nXG4gKi9cblxudmFyIG9wZW5wZ3AgPSByZXF1aXJlKCdvcGVucGdwJyk7XG5cbi8qKlxuICogQ2FsbGJhY2sgdG8gY2hlY2sgaWYgYSBrZXkgbWF0Y2hlcyB0aGUgaW5wdXRcbiAqIEBjYWxsYmFjayBtb2R1bGU6a2V5cmluZy9rZXlyaW5nLmNoZWNrQ2FsbGJhY2tcbiAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBpbnB1dCB0byBzZWFyY2ggZm9yXG4gKiBAcGFyYW0ge21vZHVsZTprZXl+S2V5fSBrZXkgVGhlIGtleSB0byBiZSBjaGVja2VkLlxuICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgaW5wdXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGtleVxuICovXG5cbi8qKlxuICogSW5pdGlhbGl6YXRpb24gcm91dGluZSBmb3IgdGhlIGtleXJpbmcuIFRoaXMgbWV0aG9kIHJlYWRzIHRoZVxuICoga2V5cmluZyBmcm9tIEhUTUw1IGxvY2FsIHN0b3JhZ2UgYW5kIGluaXRpYWxpemVzIHRoaXMgaW5zdGFuY2UuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Y2xhc3N9IFtzdG9yZUhhbmRsZXJdIGNsYXNzIGltcGxlbWVudGluZyBsb2FkKCkgYW5kIHN0b3JlKCkgbWV0aG9kc1xuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHN0b3JlSGFuZGxlcikge1xuICBpZiAoIXN0b3JlSGFuZGxlcikge1xuICAgIHN0b3JlSGFuZGxlciA9IG5ldyAocmVxdWlyZSgnLi9sb2NhbHN0b3JlLmpzJykpKCk7XG4gIH1cbiAgdGhpcy5zdG9yZUhhbmRsZXIgPSBzdG9yZUhhbmRsZXI7XG4gIHRoaXMua2V5cyA9IHRoaXMuc3RvcmVIYW5kbGVyLmxvYWQoKTtcblxuICAvKipcbiAgICogQ2FsbHMgdGhlIHN0b3JlSGFuZGxlciB0byBzYXZlIHRoZSBrZXlzXG4gICAqL1xuICB0aGlzLnN0b3JlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc3RvcmVIYW5kbGVyLnN0b3JlKHRoaXMua2V5cyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENsZWFyIHRoZSBrZXlyaW5nIC0gZXJhc2UgYWxsIHRoZSBrZXlzXG4gICAqL1xuICB0aGlzLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5rZXlzID0gW107XG4gIH07XG5cbiAgLyoqXG4gICAqIENoZWNrcyBhIGtleSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGVtYWlsIGFkZHJlc3NcbiAgICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsIGVtYWlsIGFkZHJlc3MgdG8gc2VhcmNoIGZvclxuICAgKiBAcGFyYW0ge21vZHVsZTprZXl+S2V5fSBrZXkgVGhlIGtleSB0byBiZSBjaGVja2VkLlxuICAgKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmIHRoZSBlbWFpbCBhZGRyZXNzIGlzIGRlZmluZWQgaW4gdGhlIHNwZWNpZmllZCBrZXlcbiAgICovXG4gIGZ1bmN0aW9uIGVtYWlsQ2hlY2soZW1haWwsIGtleSkge1xuICAgIGVtYWlsID0gZW1haWwudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIga2V5RW1haWxzID0ga2V5LmdldFVzZXJJZHMoKTtcbiAgICBmb3IgKHZhciBpOyBpIDwga2V5RW1haWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvL3dlIG5lZWQgdG8gZ2V0IGp1c3QgdGhlIGVtYWlsIGZyb20gdGhlIHVzZXJpZCBrZXlcbiAgICAgIGtleUVtYWlsID0ga2V5RW1haWxzW2ldLnNwbGl0KCc8JylbMV0uc3BsaXQoJz4nKVswXS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChrZXlFbWFpbCA9PSBlbWFpbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBhIGtleSB0byBzZWUgaWYgaXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGtleWlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpZCBoZXggc3RyaW5nIGtleWlkIHRvIHNlYXJjaCBmb3JcbiAgICogQHBhcmFtIHttb2R1bGU6a2V5fktleX0ga2V5IHRoZSBrZXkgdG8gYmUgY2hlY2tlZC5cbiAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiB0aGUgZW1haWwgYWRkcmVzcyBpcyBkZWZpbmVkIGluIHRoZSBzcGVjaWZpZWQga2V5XG4gICAqIEBpbm5lclxuICAgKi9cbiAgZnVuY3Rpb24gaWRDaGVjayhpZCwga2V5KSB7XG4gICAgdmFyIGtleWlkcyA9IGtleS5nZXRLZXlJZHMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleWlkcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG9wZW5wZ3AudXRpbC5oZXhzdHJkdW1wKGtleWlkc1tpXS53cml0ZSgpKSA9PSBpZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIHNlYXJjaGVzIGFsbCBwdWJsaWMga2V5cyBpbiB0aGUga2V5cmluZyBtYXRjaGluZyB0aGUgYWRkcmVzcyBvciBhZGRyZXNzIHBhcnQgb2YgdGhlIHVzZXIgaWRzXG4gICAqIEBwYXJhbSB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSBrZXlzIGFycmF5IG9mIGtleXMgdG8gc2VhcmNoXG4gICAqIEBwYXJhbSB7bW9kdWxlOmtleXJpbmcva2V5cmluZy5jaGVja0NhbGxiYWNrfSBpZGVudGl0eUZ1bmN0aW9uIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGNoZWNrcyBmb3IgYSBtYXRjaFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaWRlbnRpdHlJbnB1dCBpbnB1dCB0byBjaGVjayBhZ2FpbnN0XG4gICAqIEBwYXJhbSB7bW9kdWxlOmVudW1zLnBhY2tldH0ga2V5VHlwZSBwYWNrZXQgdHlwZXMgb2Yga2V5cyB0byBjaGVja1xuICAgKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6a2V5fktleT59IGFycmF5IG9mIGtleXMgd2hpY2ggbWF0Y2hcbiAgICovXG4gIGZ1bmN0aW9uIGNoZWNrRm9ySWRlbnRpdHlBbmRLZXlUeXBlTWF0Y2goa2V5cywgaWRlbnRpdHlGdW5jdGlvbiwgaWRlbnRpdHlJbnB1dCwga2V5VHlwZSkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgZm9yICh2YXIgcCA9IDA7IHAgPCBrZXlzLmxlbmd0aDsgcCsrKSB7XG4gICAgICB2YXIga2V5ID0ga2V5c1twXTtcbiAgICAgIHN3aXRjaCAoa2V5VHlwZSkge1xuICAgICAgICBjYXNlIG9wZW5wZ3AuZW51bXMucGFja2V0LnB1YmxpY19rZXk6XG4gICAgICAgICAgaWYgKGtleS5pc1B1YmxpYygpICYmIGlkZW50aXR5RnVuY3Rpb24oaWRlbnRpdHlJbnB1dCwga2V5KSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGtleSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9wZW5wZ3AuZW51bXMucGFja2V0LnByaXZhdGVfa2V5OlxuICAgICAgICAgIGlmIChrZXkuaXNQcml2YXRlKCkgJiYgaWRlbnRpdHlGdW5jdGlvbihpZGVudGl0eUlucHV0LCBrZXkpKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIHNlYXJjaGVzIGFsbCBwdWJsaWMga2V5cyBpbiB0aGUga2V5cmluZyBtYXRjaGluZyB0aGUgYWRkcmVzcyBvciBhZGRyZXNzIHBhcnQgb2YgdGhlIHVzZXIgaWRzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBlbWFpbCBlbWFpbCBhZGRyZXNzIHRvIHNlYXJjaCBmb3JcbiAgICogQHJldHVybiB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSBUaGUgcHVibGljIGtleXMgYXNzb2NpYXRlZCB3aXRoIHByb3ZpZGVkIGVtYWlsIGFkZHJlc3MuXG4gICAqL1xuICB0aGlzLmdldFB1YmxpY0tleUZvckFkZHJlc3MgPSBmdW5jdGlvbiAoZW1haWwpIHtcbiAgICByZXR1cm4gY2hlY2tGb3JJZGVudGl0eUFuZEtleVR5cGVNYXRjaCh0aGlzLmtleXMsIGVtYWlsQ2hlY2ssIGVtYWlsLCBvcGVucGdwLmVudW1zLnBhY2tldC5wdWJsaWNfa2V5KTtcbiAgfTtcblxuICAvKipcbiAgICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIGEgcHJpdmF0ZSBrZXkgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVtYWlsIGFkZHJlc3NcbiAgICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsIGVtYWlsIGFkZHJlc3MgdG8gc2VhcmNoIGZvclxuICAgKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHByaXZhdGUga2V5cyBmb3VuZFxuICAgKi9cbiAgdGhpcy5nZXRQcml2YXRlS2V5Rm9yQWRkcmVzcyA9IGZ1bmN0aW9uIChlbWFpbCkge1xuICAgIHJldHVybiBjaGVja0ZvcklkZW50aXR5QW5kS2V5VHlwZU1hdGNoKHRoaXMua2V5cywgZW1haWxDaGVjaywgZW1haWwsIG9wZW5wZ3AuZW51bXMucGFja2V0LnNlY3JldF9rZXkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTZWFyY2hlcyB0aGUga2V5cmluZyBmb3IgcHVibGljIGtleXMgaGF2aW5nIHRoZSBzcGVjaWZpZWQga2V5IGlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlJZCBwcm92aWRlZCBhcyBzdHJpbmcgb2YgaGV4IG51bWJlciAobG93ZXJjYXNlKVxuICAgKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHB1YmxpYyBrZXlzIGZvdW5kXG4gICAqL1xuICB0aGlzLmdldEtleXNGb3JLZXlJZCA9IGZ1bmN0aW9uIChrZXlJZCkge1xuICAgIHJldHVybiBjaGVja0ZvcklkZW50aXR5QW5kS2V5VHlwZU1hdGNoKHRoaXMua2V5cywgaWRDaGVjaywga2V5SWQsIG9wZW5wZ3AuZW51bXMucGFja2V0LnB1YmxpY19rZXkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGEga2V5IGZyb20gYW4gYXNjaWkgYXJtb3JlZCBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkIG1lc3NhZ2UgdG8gcmVhZCB0aGUga2V5cy9rZXkgZnJvbVxuICAgKi9cbiAgdGhpcy5pbXBvcnRLZXkgPSBmdW5jdGlvbiAoYXJtb3JlZCkge1xuICAgIHRoaXMua2V5cyA9IHRoaXMua2V5cy5jb25jYXQob3BlbnBncC5rZXkucmVhZEFybW9yZWQoYXJtb3JlZCkua2V5cyk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvKipcbiAgICogcmV0dXJucyB0aGUgYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBrZXkgYXQga2V5IHJpbmcgaW5kZXhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGtleSB3aXRoaW4gdGhlIGFycmF5XG4gICAqIEByZXR1cm4ge1N0cmluZ30gYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGluZyB0aGUga2V5IG9iamVjdFxuICAgKi9cbiAgdGhpcy5leHBvcnRLZXkgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXlzW2luZGV4XS5hcm1vcigpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgcHVibGljIGtleSBmcm9tIHRoZSBwdWJsaWMga2V5IGtleXJpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IHRoZSBpbmRleCBvZiB0aGUgcHVibGljIGtleSB3aXRoaW4gdGhlIHB1YmxpY0tleXMgYXJyYXlcbiAgICogQHJldHVybiB7bW9kdWxlOmtleX5LZXl9IFRoZSBwdWJsaWMga2V5IG9iamVjdCB3aGljaCBoYXMgYmVlbiByZW1vdmVkXG4gICAqL1xuICB0aGlzLnJlbW92ZUtleSA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHZhciByZW1vdmVkID0gdGhpcy5rZXlzLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICByZXR1cm4gcmVtb3ZlZDtcbiAgfTtcblxuICAvKipcbiAgICogcmV0dXJucyB0aGUgYXJtb3JlZCBtZXNzYWdlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwdWJsaWMga2V5IHBvcnRpb24gb2YgdGhlIGtleSBhdCBrZXkgcmluZyBpbmRleFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IHRoZSBpbmRleCBvZiB0aGUga2V5IHdpdGhpbiB0aGUgYXJyYXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBhcm1vcmVkIG1lc3NhZ2UgcmVwcmVzZW50aW5nIHRoZSBwdWJsaWMga2V5IG9iamVjdFxuICAgKi9cbiAgdGhpcy5leHBvcnRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXlzW2luZGV4XS50b1B1YmxpYygpLmFybW9yKCk7XG4gIH07XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBUaGUgY2xhc3MgdGhhdCBkZWFscyB3aXRoIHN0b3JhZ2Ugb2YgdGhlIGtleXJpbmcuIEN1cnJlbnRseSB0aGUgb25seSBvcHRpb24gaXMgdG8gdXNlIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gKiBAcmVxdWlyZXMgb3BlbnBncFxuICogQG1vZHVsZSBrZXlyaW5nL2xvY2Fsc3RvcmVcbiAqL1xuXG52YXIgb3BlbnBncCA9IHJlcXVpcmUoJ29wZW5wZ3AnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBMb2FkIHRoZSBrZXlyaW5nIGZyb20gSFRNTDUgbG9jYWwgc3RvcmFnZSBhbmQgaW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZS5cbiAgICogQHJldHVybiB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSBhcnJheSBvZiBrZXlzIHJldHJpZXZlZCBmcm9tIGxvY2Fsc3RvcmVcbiAgICovXG4gIHRoaXMubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJtb3JlZEtleXMgPSBKU09OLnBhcnNlKHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImFybW9yZWRLZXlzXCIpKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGlmIChhcm1vcmVkS2V5cyAhPT0gbnVsbCAmJiBhcm1vcmVkS2V5cy5sZW5ndGggIT09IDApIHtcbiAgICAgIHZhciBrZXk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFybW9yZWRLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGtleSA9IG9wZW5wZ3Aua2V5LnJlYWRBcm1vcmVkKGFybW9yZWRLZXlzW2ldKTtcbiAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBrZXlyaW5nIHRvIEhUTUw1IGxvY2FsIHN0b3JhZ2UuXG4gICAqIFRoZSBwcml2YXRlS2V5cyBhcnJheSBhbmQgcHVibGljS2V5cyBhcnJheSBnZXRzIFN0cmluZ2lmaWVkIHVzaW5nIEpTT05cbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6a2V5fktleT59IGtleXMgYXJyYXkgb2Yga2V5cyB0byBzYXZlIGluIGxvY2Fsc3RvcmVcbiAgICovXG4gIHRoaXMuc3RvcmUgPSBmdW5jdGlvbiAoa2V5cykge1xuICAgIHZhciBhcm1vcmVkS2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgYXJtb3JlZEtleXMucHVzaChrZXlzW2ldLmFybW9yKCkpO1xuICAgIH1cbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJhcm1vcmVkS2V5c1wiLCBKU09OLnN0cmluZ2lmeShhcm1vcmVkS2V5cykpO1xuICB9XG59O1xuIl19 ; \ No newline at end of file diff --git a/resources/keyring.min.js b/resources/keyring.min.js index 59c6f45a..6eab40e7 100644 --- a/resources/keyring.min.js +++ b/resources/keyring.min.js @@ -1 +1 @@ -/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.0.1 - 2013-12-22 */require=function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g")[0].trim().toLowerCase(),keyEmail==a)return!0;return!1}function d(a,b){for(var d=b.getKeyIds(),e=0;e")[0].trim().toLowerCase(),keyEmail==a)return!0;return!1}function e(a,b){for(var d=b.getKeyIds(),e=0;e i) i++; return message.substring(i + 1, message.length); - }, + } }, emsa: { @@ -6235,12 +6284,19 @@ module.exports = { // // A Digital signature algorithm implementation -/** @module crypto/public_key/dsa */ +/** + * @requires crypto/hash + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/dsa + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), hashModule = require('../hash'), - util = require('../../util'); + util = require('../../util'), + config = require('../../config'); function DSA() { // s1 = ((g**s) mod p) mod q @@ -6263,7 +6319,7 @@ function DSA() { } function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; + var usersetting = config.prefer_hash_algorithm; /* * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash @@ -6381,7 +6437,7 @@ function DSA() { module.exports = DSA; -},{"../../util":56,"../hash":12,"../random.js":23,"./jsbn.js":21}],19:[function(require,module,exports){ +},{"../../config":3,"../../util":56,"../hash":12,"../random.js":23,"./jsbn.js":21}],19:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -6401,7 +6457,12 @@ module.exports = DSA; // // ElGamal implementation -/** @module crypto/public_key/elgamal */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/elgamal + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), @@ -6439,9 +6500,18 @@ function Elgamal() { module.exports = Elgamal; },{"../../util":56,"../random.js":23,"./jsbn.js":21}],20:[function(require,module,exports){ +/** + * @requires crypto/public_key/dsa + * @requires crypto/public_key/elgamal + * @requires crypto/public_key/rsa + * @module crypto/public_key + */ module.exports = { + /** @see module:crypto/public_key/rsa */ rsa: require('./rsa.js'), + /** @see module:crypto/public_key/elgamal */ elgamal: require('./elgamal.js'), + /** @see module:crypto/public_key/dsa */ dsa: require('./dsa.js') } @@ -6480,7 +6550,10 @@ module.exports = { */ -/** @module crypto/public_key/jsbn */ +/** + * @requires util + * @module crypto/public_key/jsbn + */ var util = require('../../util'); @@ -8174,7 +8247,12 @@ BigInteger.prototype.square = bnSquare; // // RSA implementation -/** @module crypto/public_key/rsa */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/rsa + */ var BigInteger = require('./jsbn.js'), util = require('../../util'), @@ -8323,7 +8401,10 @@ module.exports = RSA; // The GPG4Browsers crypto interface -/** @module crypto/random */ +/** + * @requires type/mpi + * @module crypto/random + */ var type_mpi = require('../type/mpi.js'); @@ -8412,7 +8493,11 @@ module.exports = { }; },{"../type/mpi.js":54}],24:[function(require,module,exports){ -/** @module crypto/signature */ +/** + * @requires crypto/hash + * @requires crypto/pkcs1 + * @requires crypto/public_key + * @module crypto/signature */ var publicKey = require('./public_key'), pkcs1 = require('./pkcs1.js'), @@ -8538,11 +8623,16 @@ module.exports = { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module encoding/armor */ +/** + * @requires encoding/base64 + * @requires enums + * @requires config + * @module encoding/armor + */ -var base64 = require('./base64.js'); -var enums = require('../enums.js'); -var config = require('../config'); +var base64 = require('./base64.js'), + enums = require('../enums.js'), + config = require('../config'); /** * Finds out which Ascii Armoring type is used. This is an internal function @@ -8555,7 +8645,7 @@ var config = require('../config'); * 5 = PRIVATE KEY BLOCK * null = unknown */ -function get_type(text) { +function getType(text) { var reHeader = /^-----([^-]+)-----$\n/m; var header = text.match(reHeader); @@ -8608,7 +8698,7 @@ function get_type(text) { * @version 2011-12-16 * @returns {String} The header information */ -function armor_addheader() { +function addheader() { var result = ""; if (config.show_version) { result += "Version: " + config.versionstring + '\r\n'; @@ -8724,7 +8814,7 @@ function createcrc24(input) { * or an object with attribute "headers" containing the headers and * and an attribute "body" containing the body. */ -function split_headers(text) { +function splitHeaders(text) { var reEmptyLine = /^[\t ]*\n/m; var headers = ""; var body = text; @@ -8746,7 +8836,7 @@ function split_headers(text) { * or an object with attribute "body" containing the body * and an attribute "checksum" containing the checksum. */ -function split_checksum(text) { +function splitChecksum(text) { var reChecksumStart = /^=/m; var body = text; var checksum = ""; @@ -8767,13 +8857,14 @@ function split_checksum(text) { * @param {String} text OpenPGP armored message * @returns {Object} An object with attribute "text" containing the message text, * an attribute "data" containing the bytes and "type" for the ASCII armor type + * @static */ function dearmor(text) { var reSplit = /^-----[^-]+-----$\n/m; text = text.replace(/\r/g, ''); - var type = get_type(text); + var type = getType(text); if (!type) { throw new Error('Unknow ASCII armor type'); } @@ -8792,8 +8883,8 @@ function dearmor(text) { } if (type != 2) { - var msg = split_headers(splittext[indexBase]); - var msg_sum = split_checksum(msg.body); + var msg = splitHeaders(splittext[indexBase]); + var msg_sum = splitChecksum(msg.body); result = { data: base64.decode(msg_sum.body), @@ -8803,9 +8894,9 @@ function dearmor(text) { checksum = msg_sum.checksum; } else { // Reverse dash-escaping for msg and remove trailing whitespace at end of line - var msg = split_headers(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); - var sig = split_headers(splittext[indexBase + 1].replace(/^- /mg, '')); - var sig_sum = split_checksum(sig.body); + var msg = splitHeaders(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); + var sig = splitHeaders(splittext[indexBase + 1].replace(/^- /mg, '')); + var sig_sum = splitChecksum(sig.body); result = { text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"), @@ -8834,20 +8925,21 @@ function dearmor(text) { * @param {Integer} partindex * @param {Integer} parttotal * @returns {String} Armored text + * @static */ function armor(messagetype, body, partindex, parttotal) { var result = ""; switch (messagetype) { case enums.armor.multipart_section: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; break; case enums.armor.mutlipart_last: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n"; @@ -8857,28 +8949,28 @@ function armor(messagetype, body, partindex, parttotal) { result += "Hash: " + body.hash + "\r\n\r\n"; result += body.text.replace(/\n-/g, "\n- -"); result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body.data); result += "\r\n=" + getCheckSum(body.data) + "\r\n"; result += "-----END PGP SIGNATURE-----\r\n"; break; case enums.armor.message: result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE-----\r\n"; break; case enums.armor.public_key: result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; break; case enums.armor.private_key: result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; @@ -8907,10 +8999,18 @@ module.exports = { * provided with the application or distribution. */ -/** @module encoding/base64 */ +/** + * @module encoding/base64 + */ var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +/** + * Convert binary string to radix-64 + * @param {String} t binary string to convert + * @returns {string} radix-64 version of input string + * @static + */ function s2r(t) { var a, c, n; var r = '', @@ -8958,6 +9058,12 @@ function s2r(t) { return r; } +/** + * Convert radix-64 to binary string + * @param {String} t radix-64 string to convert + * @returns {string} binary version of input string + * @static + */ function r2s(t) { var c, n; var r = '', @@ -8983,12 +9089,15 @@ module.exports = { } },{}],27:[function(require,module,exports){ -/** @module enums */ +/** + * @module enums + */ module.exports = { /** A string to key specifier type * @enum {Integer} + * @readonly */ s2k: { simple: 0, @@ -8999,6 +9108,7 @@ module.exports = { /** RFC4880, section 9.1 * @enum {Integer} + * @readonly */ publicKey: { rsa_encrypt_sign: 1, @@ -9010,6 +9120,7 @@ module.exports = { /** RFC4880, section 9.2 * @enum {Integer} + * @readonly */ symmetric: { plaintext: 0, @@ -9026,6 +9137,7 @@ module.exports = { /** RFC4880, section 9.3 * @enum {Integer} + * @readonly */ compression: { uncompressed: 0, @@ -9038,6 +9150,7 @@ module.exports = { /** RFC4880, section 9.4 * @enum {Integer} + * @readonly */ hash: { md5: 1, @@ -9049,9 +9162,9 @@ module.exports = { sha224: 11 }, - /** A list of packet types and numeric tags associated with them. * @enum {Integer} + * @readonly */ packet: { public_key_encrypted_session_key: 1, @@ -9073,9 +9186,9 @@ module.exports = { modification_detection_code: 19 }, - /** Data types in the literal packet * @enum {Integer} + * @readonly */ literal: { /** Binary data 'b' */ @@ -9089,41 +9202,42 @@ module.exports = { /** One pass signature packet type * @enum {Integer} + * @readonly */ signature: { /** 0x00: Signature of a binary document. */ binary: 0, - /** 0x01: Signature of a canonical text document. + /** 0x01: Signature of a canonical text document.
      * Canonicalyzing the document by converting line endings. */ text: 1, - /** 0x02: Standalone signature. + /** 0x02: Standalone signature.
      * This signature is a signature of only its own subpacket contents. * It is calculated identically to a signature over a zero-lengh * binary document. Note that it doesn't make sense to have a V3 * standalone signature. */ standalone: 2, - /** 0x10: Generic certification of a User ID and Public-Key packet. + /** 0x10: Generic certification of a User ID and Public-Key packet.
      * The issuer of this certification does not make any particular * assertion as to how well the certifier has checked that the owner * of the key is in fact the person described by the User ID. */ cert_generic: 16, - /** 0x11: Persona certification of a User ID and Public-Key packet. + /** 0x11: Persona certification of a User ID and Public-Key packet.
      * The issuer of this certification has not done any verification of * the claim that the owner of this key is the User ID specified. */ cert_persona: 17, - /** 0x12: Casual certification of a User ID and Public-Key packet. + /** 0x12: Casual certification of a User ID and Public-Key packet.
      * The issuer of this certification has done some casual * verification of the claim of identity. */ cert_casual: 18, - /** 0x13: Positive certification of a User ID and Public-Key packet. + /** 0x13: Positive certification of a User ID and Public-Key packet.
      * The issuer of this certification has done substantial - * verification of the claim of identity. - * + * verification of the claim of identity.
      + *
      * Most OpenPGP implementations make their "key signatures" as 0x10 * certifications. Some implementations can issue 0x11-0x13 * certifications, but few differentiate between the types. */ cert_positive: 19, - /** 0x30: Certification revocation signature + /** 0x30: Certification revocation signature
      * This signature revokes an earlier User ID certification signature * (signature class 0x10 through 0x13) or direct-key signature * (0x1F). It should be issued by the same key that issued the @@ -9132,7 +9246,7 @@ module.exports = { * revokes, and should have a later creation date than that * certificate. */ cert_revocation: 48, - /** 0x18: Subkey Binding Signature + /** 0x18: Subkey Binding Signature
      * This signature is a statement by the top-level signing key that * indicates that it owns the subkey. This signature is calculated * directly on the primary key and subkey, and not on any User ID or @@ -9141,12 +9255,12 @@ module.exports = { * contains a 0x19 signature made by the signing subkey on the * primary key and subkey. */ subkey_binding: 24, - /** 0x19: Primary Key Binding Signature + /** 0x19: Primary Key Binding Signature
      * This signature is a statement by a signing subkey, indicating * that it is owned by the primary key and subkey. This signature * is calculated the same way as a 0x18 signature: directly on the - * primary key and subkey, and not on any User ID or other packets. - + * primary key and subkey, and not on any User ID or other packets.
      + *
      * When a signature is made over a key, the hash data starts with the * octet 0x99, followed by a two-octet length of the key, and then body * of the key packet. (Note that this is an old-style packet header for @@ -9155,7 +9269,7 @@ module.exports = { * the subkey using the same format as the main key (also using 0x99 as * the first octet). */ key_binding: 25, - /** 0x1F: Signature directly on a key + /** 0x1F: Signature directly on a key
      * This signature is calculated directly on a key. It binds the * information in the Signature subpackets to the key, and is * appropriate to be used for subpackets that provide information @@ -9164,26 +9278,27 @@ module.exports = { * about the key itself, rather than the binding between a key and a * name. */ key: 31, - /** 0x20: Key revocation signature + /** 0x20: Key revocation signature
      * The signature is calculated directly on the key being revoked. A * revoked key is not to be used. Only revocation signatures by the * key being revoked, or by an authorized revocation key, should be * considered valid revocation signatures.a */ key_revocation: 32, - /** 0x28: Subkey revocation signature + /** 0x28: Subkey revocation signature
      * The signature is calculated directly on the subkey being revoked. * A revoked subkey is not to be used. Only revocation signatures * by the top-level signature key that is bound to this subkey, or * by an authorized revocation key, should be considered valid - * revocation signatures. + * revocation signatures.
      + *
      * Key revocation signatures (types 0x20 and 0x28) * hash only the key being revoked. */ subkey_revocation: 40, - /** 0x40: Timestamp signature. + /** 0x40: Timestamp signature.
      * This signature is only meaningful for the timestamp contained in * it. */ timestamp: 64, - /** 0x50: Third-Party Confirmation signature. + /** 0x50: Third-Party Confirmation signature.
      * This signature is a signature over some other OpenPGP Signature * packet(s). It is analogous to a notary seal on the signed data. * A third-party signature SHOULD include Signature Target @@ -9196,6 +9311,7 @@ module.exports = { /** Signature subpacket type * @enum {Integer} + * @readonly */ signatureSubpacket: { signature_creation_time: 2, @@ -9226,28 +9342,30 @@ module.exports = { /** Key flags * @enum {Integer} + * @readonly */ keyFlags: { - // 0x01 - This key may be used to certify other keys. + /** 0x01 - This key may be used to certify other keys. */ certify_keys: 1, - // 0x02 - This key may be used to sign data. + /** 0x02 - This key may be used to sign data. */ sign_data: 2, - // 0x04 - This key may be used to encrypt communications. + /** 0x04 - This key may be used to encrypt communications. */ encrypt_communication: 4, - // 0x08 - This key may be used to encrypt storage. + /** 0x08 - This key may be used to encrypt storage. */ encrypt_storage: 8, - // 0x10 - The private component of this key may have been split - // by a secret-sharing mechanism. + /** 0x10 - The private component of this key may have been split + * by a secret-sharing mechanism. */ split_private_key: 16, - // 0x20 - This key may be used for authentication. + /** 0x20 - This key may be used for authentication. */ authentication: 32, - // 0x80 - The private component of this key may be in the - // possession of more than one person. + /** 0x80 - The private component of this key may be in the + * possession of more than one person. */ shared_private_key: 128 }, /** Key status * @enum {Integer} + * @readonly */ keyStatus: { invalid: 0, @@ -9259,6 +9377,7 @@ module.exports = { /** Armor type * @enum {Integer} + * @readonly */ armor: { multipart_section: 0, @@ -9291,20 +9410,45 @@ module.exports = { },{}],"pr55Tj":[function(require,module,exports){ module.exports = require('./openpgp.js'); + module.exports.key = require('./key.js'); module.exports.message = require('./message.js'); module.exports.cleartext = require('./cleartext.js'); -module.exports.util = require('./util'); +/** + * @see module:util/util + * @module util + */ +module.exports.util = require('./util/util.js'); module.exports.packet = require('./packet'); +/** + * @see module:type/mpi + * @module mpi + */ module.exports.mpi = require('./type/mpi.js'); +/** + * @see module:type/s2k + * @module s2k + */ module.exports.s2k = require('./type/s2k.js'); +/** + * @see module:type/keyid + * @module keyid + */ module.exports.keyid = require('./type/keyid.js'); +/** + * @see module:encoding/armor + * @module armor + */ module.exports.armor = require('./encoding/armor.js'); module.exports.enums = require('./enums.js'); -module.exports.config = require('./config'); +/** + * @see module:config/config + * @module config + */ +module.exports.config = require('./config/config.js'); module.exports.crypto = require('./crypto'); -},{"./cleartext.js":1,"./config":3,"./crypto":16,"./encoding/armor.js":25,"./enums.js":27,"./key.js":30,"./message.js":31,"./openpgp.js":32,"./packet":35,"./type/keyid.js":53,"./type/mpi.js":54,"./type/s2k.js":55,"./util":56}],"openpgp":[function(require,module,exports){ +},{"./cleartext.js":1,"./config/config.js":3,"./crypto":16,"./encoding/armor.js":25,"./enums.js":27,"./key.js":30,"./message.js":31,"./openpgp.js":32,"./packet":35,"./type/keyid.js":53,"./type/mpi.js":54,"./type/s2k.js":55,"./util/util.js":56}],"openpgp":[function(require,module,exports){ module.exports=require('pr55Tj'); },{}],30:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript @@ -9324,12 +9468,18 @@ module.exports=require('pr55Tj'); // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module key */ +/** + * @requires config + * @requires encoding/armor + * @requires enums + * @requires packet + * @module key + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'); /** * @class @@ -9973,6 +10123,7 @@ SubKey.prototype.verify = function(primaryKey) { * Reads an OpenPGP armored text and returns one or multiple key objects * @param {String} armoredText text to be parsed * @return {{keys: Array, err: (Array|null)}} result object with key and error arrays + * @static */ function readArmored(armoredText) { var result = {}; @@ -10014,6 +10165,7 @@ function readArmored(armoredText) { * @param {String} userId assumes already in form of "User Name " * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {module:key~Key} + * @static */ function generate(keyType, numBits, userId, passphrase) { var packetlist = new packet.list(); @@ -10084,14 +10236,20 @@ exports.generate = generate; // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module message */ +/** + * @requires config + * @requires crypto + * @requires encoding/armor + * @requires enums + * @requires packet + * @module message + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); -var crypto = require('./crypto'); -var util = require('./util'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'), + crypto = require('./crypto'); /** * @class @@ -10330,6 +10488,7 @@ Message.prototype.armor = function() { * reads an OpenPGP armored message and returns a message object * @param {String} armoredText text to be parsed * @return {module:message~Message} new message object + * @static */ function readArmored(armoredText) { //TODO how do we want to handle bad text? Exception throwing @@ -10345,6 +10504,7 @@ function readArmored(armoredText) { * creates new message object from text * @param {String} text * @return {module:message~Message} new message object + * @static */ function fromText(text) { var literalDataPacket = new packet.literal(); @@ -10360,6 +10520,7 @@ function fromText(text) { * creates new message object from binary data * @param {String} bytes * @return {module:message~Message} new message object + * @static */ function fromBinary(bytes) { var literalDataPacket = new packet.literal(); @@ -10375,7 +10536,7 @@ exports.readArmored = readArmored; exports.fromText = fromText; exports.fromBinary = fromBinary; -},{"./config":3,"./crypto":16,"./encoding/armor.js":25,"./enums.js":27,"./packet":35,"./util":56}],32:[function(require,module,exports){ +},{"./config":3,"./crypto":16,"./encoding/armor.js":25,"./enums.js":27,"./packet":35}],32:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -10399,15 +10560,23 @@ exports.fromBinary = fromBinary; * for extending and developing on top of the base library. */ -/** @module openpgp */ +/** + * @requires cleartext + * @requires config + * @requires encoding/armor + * @requires enums + * @requires message + * @requires packet + * @module openpgp + */ -var armor = require('./encoding/armor.js'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var config = require('./config'); -var message = require('./message.js'); -var cleartext = require('./cleartext.js'); -var key = require('./key.js'); +var armor = require('./encoding/armor.js'), + packet = require('./packet'), + enums = require('./enums.js'), + config = require('./config'), + message = require('./message.js'), + cleartext = require('./cleartext.js'), + key = require('./key.js'); /** @@ -10415,6 +10584,7 @@ var key = require('./key.js'); * @param {Array} keys array of keys, used to encrypt the message * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function encryptMessage(keys, text) { var msg = message.fromText(text); @@ -10429,6 +10599,7 @@ function encryptMessage(keys, text) { * @param {module:key~Key} privateKey private key with decrypted secret key data for signing * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function signAndEncryptMessage(publicKeys, privateKey, text) { var msg = message.fromText(text); @@ -10444,6 +10615,7 @@ function signAndEncryptMessage(publicKeys, privateKey, text) { * @param {module:message~Message} message the message object with the encrypted data * @return {(String|null)} decrypted message as as native JavaScript string * or null if no literal data found + * @static */ function decryptMessage(privateKey, message) { message = message.decrypt(privateKey); @@ -10458,6 +10630,7 @@ function decryptMessage(privateKey, message) { * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * decrypted message as as native JavaScript string * with verified signatures or null if no literal data found + * @static */ function decryptAndVerifyMessage(privateKey, publicKeys, message) { var result = {}; @@ -10475,6 +10648,7 @@ function decryptAndVerifyMessage(privateKey, publicKeys, message) { * @param {Array} privateKeys private key with decrypted secret key data to sign cleartext * @param {String} text cleartext * @return {String} ASCII armored message + * @static */ function signClearMessage(privateKeys, text) { var cleartextMessage = new cleartext.CleartextMessage(text); @@ -10488,6 +10662,7 @@ function signClearMessage(privateKeys, text) { * @param {module:cleartext~CleartextMessage} message cleartext message object with signatures * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * cleartext with status of verified signatures + * @static */ function verifyClearSignedMessage(publicKeys, message) { var result = {}; @@ -10508,6 +10683,7 @@ function verifyClearSignedMessage(publicKeys, message) { * @param {String} userId assumes already in form of "User Name " * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {Object} {key: Array, privateKeyArmored: Array, publicKeyArmored: Array} + * @static */ function generateKeyPair(keyType, numBits, userId, passphrase) { var result = {}; @@ -10527,25 +10703,46 @@ exports.verifyClearSignedMessage = verifyClearSignedMessage; exports.generateKeyPair = generateKeyPair; },{"./cleartext.js":1,"./config":3,"./encoding/armor.js":25,"./enums.js":27,"./key.js":30,"./message.js":31,"./packet":35}],33:[function(require,module,exports){ +/** + * @requires enums + * @module packet + */ var enums = require('../enums.js'); // This is pretty ugly, but browserify needs to have the requires explicitly written. + module.exports = { + /** @see module:packet/compressed */ compressed: require('./compressed.js'), + /** @see module:packet/sym_encrypted_integrity_protected */ sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'), + /** @see module:packet/public_key_encrypted_session_key */ public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'), + /** @see module:packet/sym_encrypted_session_key */ sym_encrypted_session_key: require('./sym_encrypted_session_key.js'), + /** @see module:packet/literal */ literal: require('./literal.js'), + /** @see module:packet/public_key */ public_key: require('./public_key.js'), + /** @see module:packet/symmetrically_encrypted */ symmetrically_encrypted: require('./symmetrically_encrypted.js'), + /** @see module:packet/marker */ marker: require('./marker.js'), + /** @see module:packet/public_subkey */ public_subkey: require('./public_subkey.js'), + /** @see module:packet/user_attribute */ user_attribute: require('./user_attribute.js'), + /** @see module:packet/one_pass_signature */ one_pass_signature: require('./one_pass_signature.js'), + /** @see module:packet/secret_key */ secret_key: require('./secret_key.js'), + /** @see module:packet/userid */ userid: require('./userid.js'), + /** @see module:packet/secret_subkey */ secret_subkey: require('./secret_subkey.js'), + /** @see module:packet/signature */ signature: require('./signature.js'), + /** @see module:packet/trust */ trust: require('./trust.js') } @@ -10574,38 +10771,47 @@ for (var i in enums.packet) { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/compressed */ +/** + * Implementation of the Compressed Data Packet (Tag 8)
      + *
      + * RFC4880 5.6: The Compressed Data packet contains compressed data. Typically, + * this packet is found as the contents of an encrypted packet, or following + * a Signature or One-Pass Signature packet, and contains a literal data packet. + * @requires compression/jxg + * @requires encoding/base64 + * @requires enums + * @module packet/compressed + */ var enums = require('../enums.js'), JXG = require('../compression/jxg.js'), base64 = require('../encoding/base64.js'); /** - * @class - * @classdesc Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. + * @constructor */ -module.exports = function packet_compressed() { - /** @type {module:packet/packetlist} */ - this.packets; - /** @type {compression} */ +module.exports = function () { + /** + * List of packets + * @type {module:packet/packetlist} + */ + this.packets = null; + /** + * Compression algorithm + * @type {compression} + */ this.algorithm = 'uncompressed'; + /** + * Compressed packet data + * @type {String} + */ this.compressed = null; /** * Parsing function for the packet. - * @param {String} input Payload of a tag 8 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of - * input at position - * @return {module:packet/compressed} Object representation + * @param {String} bytes Payload of a tag 8 packet */ this.read = function(bytes) { // One octet that gives the algorithm used to compress the packet. @@ -10619,6 +10825,10 @@ module.exports = function packet_compressed() { + /** + * Return the compressed packet. + * @return {String} binary compressed packet + */ this.write = function() { if (this.compressed == null) this.compress(); @@ -10630,7 +10840,6 @@ module.exports = function packet_compressed() { /** * Decompression method for decompressing the compressed data * read by read_packet - * @return {String} The decompressed data */ this.decompress = function() { var decompressed; @@ -10687,9 +10896,6 @@ module.exports = function packet_compressed() { /** * Compress the packet data (member decompressedData) - * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 - * @param {String} data Data to be compressed - * @return {String} The compressed data stored in attribute compressedData */ this.compress = function() { switch (this.algorithm) { @@ -10727,7 +10933,7 @@ module.exports = function packet_compressed() { var enums = require('../enums.js'); module.exports = { - list: require('./packetlist.js'), + list: require('./packetlist.js') }; var packets = require('./all_packets.js'); @@ -10753,19 +10959,23 @@ for (var i in packets) // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/literal */ +/** + * Implementation of the Literal Data Packet (Tag 11)
      + *
      + * RFC4880 5.9: A Literal Data packet contains the body of a message; data that + * is not to be further interpreted. + * @requires enums + * @requires util + * @module packet/literal + */ var util = require('../util'), enums = require('../enums.js'); /** - * @class - * @classdesc Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. + * @constructor */ -module.exports = function packet_literal() { +module.exports = function () { this.format = 'utf8'; // default format for literal data packets this.data = ''; // literal data representation as native JavaScript string or bytes this.date = new Date(); @@ -10880,18 +11090,21 @@ module.exports = function packet_literal() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/marker */ /** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * + * Implementation of the strange "Marker packet" (Tag 10)
      + *
      * RFC4880 5.8: An experimental version of PGP used this packet as the Literal * packet, but no released version of PGP generated Literal packets with this * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * + * the Marker packet.
      + *
      * Such a packet MUST be ignored when received. + * @module packet/marker + */ + +/** + * @constructor */ module.exports = function () { /** @@ -10933,24 +11146,27 @@ module.exports = function () { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/one_pass_signature */ - -var enums = require('../enums.js'), - type_keyid = require('../type/keyid.js'); - /** - * @class - * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) - * + * Implementation of the One-Pass Signature Packets (Tag 4)
      + *
      * RFC4880 5.4: * The One-Pass Signature packet precedes the signed data and contains * enough information to allow the receiver to begin calculating any * hashes needed to verify the signature. It allows the Signature * packet to be placed at the end of the message, so that the signer * can compute the entire signed message in one pass. - */ + * @requires enums + * @requires type/keyid + * @module packet/one_pass_signature +*/ -module.exports = function one_pass_signature() { +var enums = require('../enums.js'), + type_keyid = require('../type/keyid.js'); + +/** + * @constructor + */ +module.exports = function () { this.version = null; // A one-octet version number. The current version is 3. this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) @@ -11027,7 +11243,11 @@ module.exports = function one_pass_signature() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/packet */ +/** + * @requires enums + * @requires util + * @module packet/packet + */ var enums = require('../enums.js'), util = require('../util'); @@ -11271,19 +11491,24 @@ module.exports = { } },{"../enums.js":27,"../util":56}],40:[function(require,module,exports){ -/** @module packet/packetlist */ +/** + * This class represents a list of openpgp packets. + * Take care when iterating over it - the packets themselves + * are stored as numerical indices. + * @requires enums + * @requires packet + * @requires packet/packet + * @module packet/packetlist + */ var packetParser = require('./packet.js'), packets = require('./all_packets.js'), enums = require('../enums.js'); /** - * @class - * @classdesc This class represents a list of openpgp packets. - * Take care when iterating over it - the packets themselves - * are stored as numerical indices. + * @constructor */ -module.exports = function packetlist() { +module.exports = packetlist = function () { /** The number of packets contained within the list. * @readonly * @type {Integer} */ @@ -11291,7 +11516,7 @@ module.exports = function packetlist() { /** * Reads a stream of binary data and interprents it as a list of packets. - * @param {openpgp_byte_array} An array of bytes. + * @param {String} A binary string of bytes. */ this.read = function(bytes) { var i = 0; @@ -11312,7 +11537,7 @@ module.exports = function packetlist() { /** * Creates a binary representation of openpgp objects contained within the * class instance. - * @returns {openpgp_byte_array} An array of bytes containing valid openpgp packets. + * @returns {String} A binary string of bytes containing valid openpgp packets. */ this.write = function() { var bytes = ''; @@ -11462,7 +11687,20 @@ module.exports = function packetlist() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)
      + *
      + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key + */ var util = require('../util'), type_mpi = require('../type/mpi.js'), @@ -11471,15 +11709,9 @@ var util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. + * @constructor */ -module.exports = function packet_public_key() { +module.exports = function () { this.version = 4; /** Key creation date. * @type {Date} */ @@ -11488,7 +11720,7 @@ module.exports = function packet_public_key() { * @type {module:type/mpi} */ this.mpi = []; /** Public key algorithm - * @type {openpgp.publickey} */ + * @type {module:enums.publicKey} */ this.algorithm = 'rsa_sign'; // time in days (V3 only) this.expirationTimeV3 = 0; @@ -11499,11 +11731,9 @@ module.exports = function packet_public_key() { * 5.5.2 Public-Key Packet Formats * called by read_tag<num> * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input * @return {Object} This object with attributes set by the parser */ - this.readPublicKey = this.read = function(bytes) { + this.read = function(bytes) { var pos = 0; // A one-octet version number (3 or 4). this.version = bytes.charCodeAt(pos++); @@ -11544,19 +11774,22 @@ module.exports = function packet_public_key() { } else { throw new Error('Version ' + version + ' of the key packet is unsupported.'); } - } + }; - /* + /** + * Alias of read() + * @function module:packet/public_key#readPublicKey + * @see module:packet/public_key#read + */ + this.readPublicKey = this.read; + + /** * Same as write_private_key, but has less information because of * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, + * @return {Object} {body: [string]OpenPGP packet body contents, * header: [string] OpenPGP packet header, string: [string] header+body} */ - this.writePublicKey = this.write = function() { + this.write = function() { // Version var result = String.fromCharCode(this.version); result += util.writeDate(this.created); @@ -11572,16 +11805,25 @@ module.exports = function packet_public_key() { } return result; - } + }; - // Write an old version packet - it's used by some of the internal routines. + /** + * Alias of write() + * @function module:packet/public_key#writePublicKey + * @see module:packet/public_key#write + */ + this.writePublicKey = this.write; + + /** + * Write an old version packet - it's used by some of the internal routines. + */ this.writeOld = function() { var bytes = this.writePublicKey(); return String.fromCharCode(0x99) + util.writeNumber(bytes.length, 2) + bytes; - } + }; /** * Calculates the key id of the key @@ -11595,7 +11837,7 @@ module.exports = function packet_public_key() { keyid.read(this.mpi[0].write().substr(-8)); } return keyid; - } + }; /** * Calculates the fingerprint of the key @@ -11613,9 +11855,8 @@ module.exports = function packet_public_key() { } return crypto.hash.md5(toHash) } - } - -} + }; +}; },{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56}],42:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript @@ -11635,19 +11876,9 @@ module.exports = function packet_public_key() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key_encrypted_session_key */ - -var type_keyid = require('../type/keyid.js'), - util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)
      + *
      * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -11659,8 +11890,24 @@ var type_keyid = require('../type/keyid.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key_encrypted_session_key */ -module.exports = function packet_public_key_encrypted_session_key() { + +var type_keyid = require('../type/keyid.js'), + util = require('../util'), + type_mpi = require('../type/mpi.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.version = 3; this.publicKeyId = new type_keyid(); @@ -11710,7 +11957,7 @@ module.exports = function packet_public_key_encrypted_session_key() { i += mpi.read(bytes.substr(i)); this.encrypted.push(mpi); } - } + }; /** * Create a string representation of a tag 1 packet @@ -11742,7 +11989,7 @@ module.exports = function packet_public_key_encrypted_session_key() { } return result; - } + }; this.encrypt = function(key) { var data = String.fromCharCode( @@ -11761,7 +12008,7 @@ module.exports = function packet_public_key_encrypted_session_key() { this.publicKeyAlgorithm, key.mpi, mpi); - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -11792,7 +12039,7 @@ module.exports = function packet_public_key_encrypted_session_key() { this.sessionKeyAlgorithm = enums.read(enums.symmetric, decoded.charCodeAt(0)); } - } + }; }; },{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56}],43:[function(require,module,exports){ @@ -11813,12 +12060,19 @@ module.exports = function packet_public_key_encrypted_session_key() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_subkey */ +/** + * @requires packet/public_key + * @module packet/public_subkey + */ -var public_key = require('./public_key.js'); +var publicKey = require('./public_key.js'); -module.exports = function public_subkey() { - public_key.call(this); +/** + * @constructor + * @extends module:packet/public_key + */ +module.exports = function () { + publicKey.call(this); } },{"./public_key.js":41}],44:[function(require,module,exports){ @@ -11839,7 +12093,21 @@ module.exports = function public_subkey() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)
      + *
      + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires packet/public_key + * @requires type/mpi + * @requires type/s2k + * @requires util + * @module packet/secret_key + */ var publicKey = require('./public_key.js'), enums = require('../enums.js'), @@ -11849,14 +12117,8 @@ var publicKey = require('./public_key.js'), type_s2k = require('../type/s2k.js'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) + * @constructor * @extends module:packet/public_key - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. */ module.exports = function () { publicKey.call(this); @@ -12009,9 +12271,8 @@ module.exports = function () { /** * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed + * @link module:packet/secret_key.isDecrypted should be + * false otherwise a call to this function is not needed * * @param {String} str_passphrase The passphrase for this private key * as string @@ -12100,12 +12361,19 @@ module.exports.prototype = new publicKey(); // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_subkey */ +/** + * @requires packet/secret_key + * @module packet/secret_subkey + */ -var secret_key = require('./secret_key.js'); +var secretKey = require('./secret_key.js'); -module.exports = function secret_subkey() { - secret_key.call(this); +/** + * @constructor + * @extends module:packet/secret_key + */ +module.exports = function () { + secretKey.call(this); } },{"./secret_key.js":44}],46:[function(require,module,exports){ @@ -12126,7 +12394,21 @@ module.exports = function secret_subkey() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/signature */ +/** + * Implementation of the Signature Packet (Tag 2)
      + *
      + * RFC4480 5.2: + * A Signature packet describes a binding between some public key and + * some data. The most common signatures are a signature of a file or a + * block of text, and a signature that is a certification of a User ID. + * @requires crypto + * @requires enums + * @requires packet/packet + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/signature + */ var util = require('../util'), packet = require('./packet.js'), @@ -12136,15 +12418,9 @@ var util = require('../util'), type_keyid = require('../type/keyid.js'); /** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. + * @constructor */ -module.exports = function packet_signature() { +module.exports = packetSignature = function () { this.version = 4; this.signatureType = null; @@ -12205,7 +12481,7 @@ module.exports = function packet_signature() { case 3: // One-octet length of following hashed material. MUST be 5. if (bytes.charCodeAt(i++) != 5) - util.print_debug("openpgp.packet.signature.js\n" + + util.print_debug("packet/signature.js\n" + 'invalid One-octet length of following hashed material.' + 'MUST be 5. @:' + (i - 1)); @@ -12602,7 +12878,7 @@ module.exports = function packet_signature() { break; case 32: // Embedded Signature - this.embeddedSignature = new packet_signature(); + this.embeddedSignature = new packetSignature(); this.embeddedSignature.read(bytes.substr(mypos)); break; default: @@ -12760,24 +13036,27 @@ module.exports = function packet_signature() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_integrity_protected */ - -var util = require('../util'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * + * Implementation of the Sym. Encrypted Integrity Protected Data + * Packet (Tag 18)
      + *
      * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is * a variant of the Symmetrically Encrypted Data packet. It is a new feature * created for OpenPGP that addresses the problem of detecting a modification to * encrypted data. It is used in combination with a Modification Detection Code * packet. + * @requires crypto + * @requires util + * @module packet/sym_encrypted_integrity_protected */ -module.exports = function packet_sym_encrypted_integrity_protected() { +var util = require('../util'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { /** The encrypted payload. */ this.encrypted = null; // string /** @@ -12787,12 +13066,11 @@ module.exports = function packet_sym_encrypted_integrity_protected() { * @type {Boolean} */ this.modification = false; - this.packets; + this.packets = null; this.read = function(bytes) { - // - A one-octet version number. The only currently defined value is - // 1. + // - A one-octet version number. The only currently defined value is 1. var version = bytes.charCodeAt(0); if (version != 1) { @@ -12803,13 +13081,13 @@ module.exports = function packet_sym_encrypted_integrity_protected() { // operating in Cipher Feedback mode with shift amount equal to the // block size of the cipher (CFB-n where n is the block size). this.encrypted = bytes.substr(1); - } + }; this.write = function() { return String.fromCharCode(1) // Version + this.encrypted; - } + }; this.encrypt = function(sessionKeyAlgorithm, key) { var bytes = this.packets.write() @@ -12832,7 +13110,7 @@ module.exports = function packet_sym_encrypted_integrity_protected() { this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false).substring(0, prefix.length + tohash.length); - } + }; /** * Decrypts the encrypted data contained in this object read_packet must @@ -12860,7 +13138,7 @@ module.exports = function packet_sym_encrypted_integrity_protected() { throw new Error('Modification detected.'); } else this.packets.read(decrypted.substr(0, decrypted.length - 22)); - } + }; }; },{"../crypto":16,"../util":56}],48:[function(require,module,exports){ @@ -12881,16 +13159,9 @@ module.exports = function packet_sym_encrypted_integrity_protected() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_session_key */ - -var type_s2k = require('../type/s2k.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)
      + *
      * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -12902,8 +13173,20 @@ var type_s2k = require('../type/s2k.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/s2k + * @module packet/sym_encrypted_session_key */ -module.exports = function packet_sym_encrypted_session_key() { + +var type_s2k = require('../type/s2k.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 3; this.sessionKeyEncryptionAlgorithm = null; this.sessionKeyAlgorithm = 'aes256'; @@ -12939,7 +13222,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKeyEncryptionAlgorithm = algo } else this.sessionKeyAlgorithm = algo; - } + }; this.write = function() { var algo = this.encrypted == null ? @@ -12953,7 +13236,7 @@ module.exports = function packet_sym_encrypted_session_key() { if (this.encrypted != null) bytes += this.encrypted; return bytes; - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -12982,7 +13265,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKey = decrypted.substr(1); } - } + }; this.encrypt = function(passphrase) { var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); @@ -12997,7 +13280,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), this.sessionKeyEncryptionAlgorithm, key, private_key, true); - } + }; }; },{"../crypto":16,"../enums.js":27,"../type/s2k.js":55}],49:[function(require,module,exports){ @@ -13018,34 +13301,36 @@ module.exports = function packet_sym_encrypted_session_key() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/symmetrically_encrypted */ - -var crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) - * + * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
      + *
      * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted * with a symmetric-key algorithm. When it has been decrypted, it contains other * packets (usually a literal data packet or compressed data packet, but in * theory other Symmetrically Encrypted Data packets or sequences of packets * that form whole OpenPGP messages). + * @requires crypto + * @module packet/symmetrically_encrypted */ -module.exports = function packet_symmetrically_encrypted() { +var crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.encrypted = null; /** Decrypted packets contained within. * @type {module:packet/packetlist} */ - this.packets; + this.packets = null; this.read = function(bytes) { this.encrypted = bytes; - } + }; this.write = function() { return this.encrypted; - } + }; /** * Symmetrically decrypt the packet data @@ -13055,25 +13340,31 @@ module.exports = function packet_symmetrically_encrypted() { * @param {String} key * Key as string with the corresponding length to the * algorithm - * @return The decrypted data; */ this.decrypt = function(sessionKeyAlgorithm, key) { var decrypted = crypto.cfb.decrypt( sessionKeyAlgorithm, key, this.encrypted, true); this.packets.read(decrypted); - } + }; this.encrypt = function(algo, key) { var data = this.packets.write(); this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(algo), algo, data, key, true); - } + }; }; },{"../crypto":16}],50:[function(require,module,exports){ -module.exports = function packet_trust() { +/** + * @module packet/trust + */ + +/** + * @constructor + */ +module.exports = function () { }; @@ -13095,49 +13386,53 @@ module.exports = function packet_trust() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/user_attribute */ - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. +/** + * Implementation of the User Attribute Packet (Tag 17)
      + *
      + * The User Attribute packet is a variation of the User ID packet. It + * is capable of storing more types of data than the User ID packet, + * which is limited to text. Like the User ID packet, a User Attribute + * packet may be certified by the key owner ("self-signed") or any other + * key owner who cares to certify it. Except as noted, a User Attribute + * packet may be used anywhere that a User ID packet may be used. + *
      + * While User Attribute packets are not a required part of the OpenPGP + * standard, implementations SHOULD provide at least enough + * compatibility to properly handle a certification signature on the + * User Attribute packet. A simple way to do this is by treating the + * User Attribute packet as a User ID packet with opaque contents, but + * an implementation may use any method desired. + * module packet/user_attribute + * @module packet/user_attribute */ -module.exports = function packet_user_attribute() { + +var util = require('../util'), + packet = require('./packet.js'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 17; this.attributes = []; /** * parsing function for a user attribute packet (tag 17). * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {module:packet/user_attribute} object representation */ this.read = function(bytes) { var i = 0; while (i < bytes.length) { - var len = openpgp_packet.read_simple_length(bytes); - + var len = packet.readSimpleLength(bytes.substr(i)); i += len.offset; + this.attributes.push(bytes.substr(i, len.len)); i += len.len; } - } + }; }; -},{}],52:[function(require,module,exports){ +},{"../util":56,"./packet.js":39}],52:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -13155,20 +13450,24 @@ module.exports = function packet_user_attribute() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/userid */ - -var util = require('../util'); - /** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) + * Implementation of the User ID Packet (Tag 13)
      + *
      * A User ID packet consists of UTF-8 text that is intended to represent * the name and email address of the key holder. By convention, it * includes an RFC 2822 [RFC2822] mail name-addr, but there are no * restrictions on its content. The packet length in the header - * specifies the length of the User ID. + * specifies the length of the User ID. + * @requires util + * @module packet/userid */ -module.exports = function packet_userid() { + +var util = require('../util'); + +/** + * @constructor + */ +module.exports = function () { /** A string containing the user id. Usually in the form * John Doe * @type {String} @@ -13179,23 +13478,18 @@ module.exports = function packet_userid() { /** * Parsing function for a user id packet (tag 13). * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input - * at position - * @return {module:packet/userid} object representation */ - this.read = function(bytes) { + this.read = function (bytes) { this.userid = util.decode_utf8(bytes); - } + }; /** * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe + *
      + * A Key ID is an eight-octet scalar that identifies a key. + * Implementations SHOULD NOT assume that Key IDs are unique. The + * section "Enhanced Key Formats" below describes how Key IDs are + * formed. + * @requires util + * @module type/keyid + */ var util = require('../util'); /** - * @class - * @classdesc Implementation of type key id (RFC4880 3.3) - * A Key ID is an eight-octet scalar that identifies a key. - Implementations SHOULD NOT assume that Key IDs are unique. The - section "Enhanced Key Formats" below describes how Key IDs are - formed. + * @constructor */ -module.exports = function keyid() { +module.exports = function () { this.bytes = ''; @@ -13236,30 +13534,27 @@ module.exports = function keyid() { /** * Parsing method for a key id * @param {String} input Input to read the key id from - * @param {integer} position Position where to start reading the key - * id from input - * @return {module:type/keyid} This object */ this.read = function(bytes) { this.bytes = bytes.substr(0, 8); - } + }; this.write = function() { return this.bytes; - } + }; this.toHex = function() { return util.hexstrdump(this.bytes); - } + }; this.equals = function(keyid) { return this.bytes == keyid.bytes; - } + }; this.isNull = function() { return this.bytes === ''; - } -} + }; +}; module.exports.mapToHex = function(keyId) { return keyId.toHex(); @@ -13288,20 +13583,25 @@ module.exports.mapToHex = function(keyId) { // - MPI size: (a << 8) | b // - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) -/** @module type/mpi */ - -var BigInteger = require('../crypto/public_key/jsbn.js'), - util = require('../util'); - /** - * @class - * @classdescImplementation of type MPI (RFC4880 3.2) + * Implementation of type MPI (RFC4880 3.2)
      + *
      * Multiprecision integers (also called MPIs) are unsigned integers used * to hold large integers such as the ones used in cryptographic * calculations. * An MPI consists of two pieces: a two-octet scalar that is the length * of the MPI in bits followed by a string of octets that contain the * actual integer. + * @requires crypto/public_key/jsbn + * @requires util + * @module type/mpi + */ + +var BigInteger = require('../crypto/public_key/jsbn.js'), + util = require('../util'); + +/** + * @constructor */ module.exports = function mpi() { /** An implementation dependent integer */ @@ -13310,11 +13610,7 @@ module.exports = function mpi() { /** * Parsing function for a mpi (RFC 4880 3.2). * @param {String} input Payload of mpi data - * @param {Integer} position Position to start reading from the input - * string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {module:type/mpi} Object representation + * @return {Integer} Length of data read */ this.read = function(bytes) { var bits = (bytes.charCodeAt(0) << 8) | bytes.charCodeAt(1); @@ -13335,19 +13631,19 @@ module.exports = function mpi() { this.fromBytes(raw); return 2 + bytelen; - } + }; this.fromBytes = function(bytes) { this.data = new BigInteger(util.hexstrdump(bytes), 16); - } + }; this.toBytes = function() { return this.write().substr(2); - } + }; this.byteLength = function() { return this.toBytes().length; - } + }; /** * Converts the mpi object to a string as specified in RFC4880 3.2 @@ -13355,15 +13651,15 @@ module.exports = function mpi() { */ this.write = function() { return this.data.toMPI(); - } + }; this.toBigInteger = function() { return this.data.clone(); - } + }; this.fromBigInteger = function(bn) { this.data = bn.clone(); - } + }; } },{"../crypto/public_key/jsbn.js":21,"../util":56}],55:[function(require,module,exports){ @@ -13384,39 +13680,45 @@ module.exports = function mpi() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module type/s2k */ +/** + * Implementation of the String-to-key specifier (RFC4880 3.7)
      + *
      + * String-to-key (S2K) specifiers are used to convert passphrase strings + * into symmetric-key encryption/decryption keys. They are used in two + * places, currently: to encrypt the secret part of private keys in the + * private keyring, and to convert passphrases to encryption keys for + * symmetrically encrypted messages. + * @requires crypto + * @requires enums + * @requires util + * @module type/s2k + */ var enums = require('../enums.js'), util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. + * @constructor */ module.exports = function s2k() { - /** @type {openpgp.hash} */ + /** @type {module:enums.hash} */ this.algorithm = 'sha256'; - /** @type {module:type/s2k} */ + /** @type {module:enums.s2k} */ this.type = 'iterated'; this.c = 96; - /** Eight bytes of salt. - * @type {openpgp_byte_array} + /** Eight bytes of salt in a binary string. + * @type {String} */ this.salt = crypto.random.getRandomBytes(8); - // Exponen bias, defined in RFC4880 + // Exponent bias, defined in RFC4880 var expbias = 6; this.get_count = function() { return (16 + (this.c & 15)) << ((this.c >> 4) + expbias); - } + }; /** * Parsing function for a string-to-key specifier (RFC 4880 3.7). @@ -13466,7 +13768,7 @@ module.exports = function s2k() { } return i; - } + }; /** @@ -13487,10 +13789,10 @@ module.exports = function s2k() { bytes += this.salt; bytes += String.fromCharCode(this.c); break; - }; + } return bytes; - } + }; /** * Produces a key using the specified passphrase and the defined @@ -13527,7 +13829,7 @@ module.exports = function s2k() { isp = isp.substr(0, count); return crypto.hash.digest(algorithm, prefix + isp); - }; + } } var result = '', @@ -13539,8 +13841,8 @@ module.exports = function s2k() { } return result.substr(0, numBytes); - } -} + }; +}; },{"../crypto":16,"../enums.js":27,"../util":56}],56:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript @@ -13560,20 +13862,16 @@ module.exports = function s2k() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module util/util */ +/** + * This object contains utility functions + * @requires config + * @module util/util + */ var config = require('../config'); -/** - * - * This object contains utility functions - * - * @class - * @classdesc Implementation of the util object - */ -var Util = function() { - - this.readNumber = function(bytes) { +module.exports = { + readNumber: function (bytes) { var n = 0; for (var i = 0; i < bytes.length; i++) { @@ -13582,37 +13880,33 @@ var Util = function() { } return n; - }; + }, - this.writeNumber = function(n, bytes) { + writeNumber: function (n, bytes) { var b = ''; for (var i = 0; i < bytes; i++) { b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); } return b; - }; + }, - - - this.readDate = function(bytes) { + readDate: function (bytes) { var n = this.readNumber(bytes); var d = new Date(); d.setTime(n * 1000); return d; - }; + }, - this.writeDate = function(time) { + writeDate: function (time) { var numeric = Math.round(time.getTime() / 1000); return this.writeNumber(numeric, 4); - }; + }, - this.emailRegEx = /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/; + emailRegEx: /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/, - this.debug = false; - - this.hexdump = function(str) { + hexdump: function (str) { var r = []; var e = str.length; var c = 0; @@ -13627,14 +13921,14 @@ var Util = function() { r.push("\n "); } return r.join(''); - }; + }, /** * Create hexstring from a binary * @param {String} str String to convert * @return {String} String containing the hexadecimal values */ - this.hexstrdump = function(str) { + hexstrdump: function (str) { if (str == null) return ""; var r = []; @@ -13647,26 +13941,26 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** * Create binary string from a hex encoded string * @param {String} str Hex string to convert * @return {String} String containing the binary values */ - this.hex2bin = function(hex) { + hex2bin: function (hex) { var str = ''; for (var i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); return str; - }; + }, /** * Creating a hex string from an binary array of integers (0..255) * @param {String} str Array of bytes to convert * @return {String} Hexadecimal representation of the array */ - this.hexidump = function(str) { + hexidump: function (str) { var r = []; var e = str.length; var c = 0; @@ -13677,7 +13971,7 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** @@ -13685,32 +13979,29 @@ var Util = function() { * @param {String} str The string to convert * @return {String} A valid squence of utf8 bytes */ - this.encode_utf8 = function(str) { + encode_utf8: function (str) { return unescape(encodeURIComponent(str)); - }; + }, /** * Convert a string of utf8 bytes to a native javascript string * @param {String} utf8 A valid squence of utf8 bytes * @return {String} A native javascript string */ - this.decode_utf8 = function(utf8) { + decode_utf8: function (utf8) { try { return decodeURIComponent(escape(utf8)); } catch (e) { return utf8; } - }; + }, - var str2bin = function(str, result) { - for (var i = 0; i < str.length; i++) { - result[i] = str.charCodeAt(i); - } - - return result; - }; - - var bin2str = function(bin) { + /** + * Convert an array of integers(0.255) to a string + * @param {Array} bin An array of (binary) integers to convert + * @return {String} The string representation of the array + */ + bin2str: function (bin) { var result = []; for (var i = 0; i < bin.length; i++) { @@ -13718,53 +14009,57 @@ var Util = function() { } return result.join(''); - }; + }, + + _str2bin: function (str, result) { + for (var i = 0; i < str.length; i++) { + result[i] = str.charCodeAt(i); + } + + return result; + }, /** * Convert a string to an array of integers(0.255) * @param {String} str String to convert * @return {Array} An array of (binary) integers */ - this.str2bin = function(str) { - return str2bin(str, new Array(str.length)); - }; + str2bin: function (str) { + return this._str2bin(str, new Array(str.length)); + }, - /** - * Convert an array of integers(0.255) to a string - * @param {Array} bin An array of (binary) integers to convert - * @return {String} The string representation of the array - */ - this.bin2str = bin2str; - /** * Convert a string to a Uint8Array * @param {String} str String to convert * @return {Uint8Array} The array of (binary) integers */ - this.str2Uint8Array = function(str) { - return str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); - }; + str2Uint8Array: function (str) { + return this._str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); + }, /** * Convert a Uint8Array to a string. This currently functions - * the same as bin2str. + * the same as bin2str. + * @function module:util/util.Uint8Array2str * @param {Uint8Array} bin An array of (binary) integers to convert * @return {String} String representation of the array */ - this.Uint8Array2str = bin2str; + Uint8Array2str: function (bin) { + return this.bin2str(bin); + }, /** - * Calculates a 16bit sum of a string by adding each character + * Calculates a 16bit sum of a string by adding each character * codes modulus 65535 * @param {String} text String to create a sum of - * @return {Integer} An integer containing the sum of all character + * @return {Integer} An integer containing the sum of all character * codes % 65535 */ - this.calc_checksum = function(text) { + calc_checksum: function (text) { var checksum = { s: 0, - add: function(sadd) { + add: function (sadd) { this.s = (this.s + sadd) % 65536; } }; @@ -13772,42 +14067,42 @@ var Util = function() { checksum.add(text.charCodeAt(i)); } return checksum.s; - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * @param {String} str String of the debug message */ - this.print_debug = function(str) { + print_debug: function (str) { if (config.debug) { console.log(str); } - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * Different than print_debug because will call hexstrdump iff necessary. * @param {String} str String of the debug message */ - this.print_debug_hexstr_dump = function(str, strToHex) { + print_debug_hexstr_dump: function (str, strToHex) { if (config.debug) { str = str + this.hexstrdump(strToHex); console.log(str); } - }; + }, - this.getLeftNBits = function(string, bitcount) { + getLeftNBits: function (string, bitcount) { var rest = bitcount % 8; if (rest == 0) return string.substring(0, bitcount / 8); var bytes = (bitcount - rest) / 8 + 1; var result = string.substring(0, bytes); return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; + }, /** * Shifting a string to n bits right @@ -13816,7 +14111,7 @@ var Util = function() { * than 9) * @return {String} Resulting string. */ - this.shiftRight = function(value, bitcount) { + shiftRight: function (value, bitcount) { var temp = util.str2bin(value); if (bitcount % 8 != 0) { for (var i = temp.length - 1; i >= 0; i--) { @@ -13828,13 +14123,13 @@ var Util = function() { return value; } return util.bin2str(temp); - }; + }, /** * Return the algorithm type as string * @return {String} String representing the message type */ - this.get_hashAlgorithmString = function(algo) { + get_hashAlgorithmString: function (algo) { switch (algo) { case 1: return "MD5"; @@ -13852,16 +14147,9 @@ var Util = function() { return "SHA224"; } return "unknown"; - }; - + } }; -/** - * an instance that should be used. - */ - -module.exports = new Util(); - },{"../config":3}]},{},[]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NsZWFydGV4dC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY29tcHJlc3Npb24vanhnLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jb25maWcvY29uZmlnLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2ZiLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2Flcy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9ibG93ZmlzaC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9kZXMuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvdHdvZmlzaC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NyeXB0by5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9oYXNoL21kNS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvcmlwZS1tZC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvc2hhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wa2NzMS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvZHNhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9lbGdhbWFsLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9pbmRleC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvanNibi5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvcnNhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcmFuZG9tLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vc2lnbmF0dXJlLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9lbmNvZGluZy9hcm1vci5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvZW5jb2RpbmcvYmFzZTY0LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9lbnVtcy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvbWVzc2FnZS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvb3BlbnBncC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2FsbF9wYWNrZXRzLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvY29tcHJlc3NlZC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2luZGV4LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvbGl0ZXJhbC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L21hcmtlci5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L29uZV9wYXNzX3NpZ25hdHVyZS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3BhY2tldC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3BhY2tldGxpc3QuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfa2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfc3Via2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc2VjcmV0X2tleS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3NlY3JldF9zdWJrZXkuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zaWduYXR1cmUuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC90cnVzdC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3VzZXJfYXR0cmlidXRlLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvdXNlcmlkLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL2tleWlkLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL21waS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvdHlwZS9zMmsuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3V0aWwvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ252Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5bENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM3FEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdHZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25UQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeG5CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RFQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIGNsZWFydGV4dCAqL1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYW4gT3BlblBHUCBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2UuXG4gKiBTZWUgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg4MCNzZWN0aW9uLTdcbiAqIEBwYXJhbSAge1N0cmluZ30gICAgIHRleHQgICAgICAgVGhlIGNsZWFydGV4dCBvZiB0aGUgc2lnbmVkIG1lc3NhZ2VcbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH0gcGFja2V0bGlzdCBUaGUgcGFja2V0bGlzdCB3aXRoIHNpZ25hdHVyZSBwYWNrZXRzIG9yIHVuZGVmaW5lZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBtZXNzYWdlIG5vdCB5ZXQgc2lnbmVkXG4gKi9cblxuZnVuY3Rpb24gQ2xlYXJ0ZXh0TWVzc2FnZSh0ZXh0LCBwYWNrZXRsaXN0KSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDbGVhcnRleHRNZXNzYWdlKSkge1xuICAgIHJldHVybiBuZXcgQ2xlYXJ0ZXh0TWVzc2FnZShwYWNrZXRsaXN0KTtcbiAgfVxuICAvLyBub3JtYWxpemUgRU9MIHRvIGNhbm9uaWNhbCBmb3JtIDxDUj48TEY+XG4gIHRoaXMudGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKS5yZXBsYWNlKC9bXFx0IF0rXFxuL2csIFwiXFxuXCIpLnJlcGxhY2UoL1xcbi9nLFwiXFxyXFxuXCIpO1xuICB0aGlzLnBhY2tldHMgPSBwYWNrZXRsaXN0IHx8IG5ldyBwYWNrZXQubGlzdCgpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGtleSBJRHMgb2YgdGhlIGtleXMgdGhhdCBzaWduZWQgdGhlIGNsZWFydGV4dCBtZXNzYWdlXG4gKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6dHlwZS9rZXlpZD59IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuZ2V0U2lnbmluZ0tleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBzaWduYXR1cmVMaXN0ID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5zaWduYXR1cmUpO1xuICBzaWduYXR1cmVMaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAga2V5SWRzLnB1c2gocGFja2V0Lmlzc3VlcktleUlkKTtcbiAgfSk7XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG4vKipcbiAqIFNpZ24gdGhlIGNsZWFydGV4dCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHByaXZhdGVLZXlzIHByaXZhdGUga2V5cyB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uKHByaXZhdGVLZXlzKSB7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7ICBcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldFRleHQodGhpcy50ZXh0KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcml2YXRlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gZW51bXMuc2lnbmF0dXJlLnRleHQ7XG4gICAgc2lnbmF0dXJlUGFja2V0Lmhhc2hBbGdvcml0aG0gPSBjb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuICAgIHZhciBzaWduaW5nS2V5UGFja2V0ID0gcHJpdmF0ZUtleXNbaV0uZ2V0U2lnbmluZ0tleVBhY2tldCgpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBzaWduaW5nS2V5UGFja2V0LmFsZ29yaXRobTtcbiAgICBpZiAoIXNpZ25pbmdLZXlQYWNrZXQuaXNEZWNyeXB0ZWQpIHRocm93IG5ldyBFcnJvcignUHJpdmF0ZSBrZXkgaXMgbm90IGRlY3J5cHRlZC4nKTtcbiAgICBzaWduYXR1cmVQYWNrZXQuc2lnbihzaWduaW5nS2V5UGFja2V0LCBsaXRlcmFsRGF0YVBhY2tldCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKHNpZ25hdHVyZVBhY2tldCk7XG4gIH1cbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdDtcbn07XG5cbi8qKlxuICogVmVyaWZ5IHNpZ25hdHVyZXMgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0ge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybiB7QXJyYXk8e2tleWlkOiBtb2R1bGU6dHlwZS9rZXlpZCwgdmFsaWQ6IEJvb2xlYW59Pn0gbGlzdCBvZiBzaWduZXIncyBrZXlpZCBhbmQgdmFsaWRpdHkgb2Ygc2lnbmF0dXJlXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uKHB1YmxpY0tleXMpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgc2lnbmF0dXJlTGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIC8vIHdlIGFzc3VtZSB0aGF0IGNsZWFydGV4dCBzaWduYXR1cmUgaXMgZ2VuZXJhdGVkIGJhc2VkIG9uIFVURjggY2xlYXJ0ZXh0XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldFRleHQodGhpcy50ZXh0KTtcbiAgcHVibGljS2V5cy5mb3JFYWNoKGZ1bmN0aW9uKHB1YktleSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmF0dXJlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHB1YmxpY0tleVBhY2tldCA9IHB1YktleS5nZXRQdWJsaWNLZXlQYWNrZXQoW3NpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWRdKTtcbiAgICAgIGlmIChwdWJsaWNLZXlQYWNrZXQpIHtcbiAgICAgICAgdmFyIHZlcmlmaWVkU2lnID0ge307XG4gICAgICAgIHZlcmlmaWVkU2lnLmtleWlkID0gc2lnbmF0dXJlTGlzdFtpXS5pc3N1ZXJLZXlJZDtcbiAgICAgICAgdmVyaWZpZWRTaWcudmFsaWQgPSBzaWduYXR1cmVMaXN0W2ldLnZlcmlmeShwdWJsaWNLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICAgICAgcmVzdWx0LnB1c2godmVyaWZpZWRTaWcpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBHZXQgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IGNsZWFydGV4dCBvZiBtZXNzYWdlXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgLy8gbm9ybWFsaXplIGVuZCBvZiBsaW5lIHRvIFxcblxuICByZXR1cm4gdGhpcy50ZXh0LnJlcGxhY2UoL1xcclxcbi9nLFwiXFxuXCIpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIEFTQ0lJIGFybW9yZWQgdGV4dCBvZiBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ30gQVNDSUkgYXJtb3JcbiAqL1xuQ2xlYXJ0ZXh0TWVzc2FnZS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGJvZHkgPSB7XG4gICAgaGFzaDogZW51bXMucmVhZChlbnVtcy5oYXNoLCBjb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtKS50b1VwcGVyQ2FzZSgpLFxuICAgIHRleHQ6IHRoaXMudGV4dCxcbiAgICBkYXRhOiB0aGlzLnBhY2tldHMud3JpdGUoKVxuICB9XG4gIHJldHVybiBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3Iuc2lnbmVkLCBib2R5KTtcbn07XG5cblxuLyoqXG4gKiByZWFkcyBhbiBPcGVuUEdQIGNsZWFydGV4dCBzaWduZWQgbWVzc2FnZSBhbmQgcmV0dXJucyBhIENsZWFydGV4dE1lc3NhZ2Ugb2JqZWN0XG4gKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgdGV4dCB0byBiZSBwYXJzZWRcbiAqIEByZXR1cm4ge21vZHVsZTpjbGVhcnRleHR+Q2xlYXJ0ZXh0TWVzc2FnZX0gbmV3IGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdFxuICovXG5mdW5jdGlvbiByZWFkQXJtb3JlZChhcm1vcmVkVGV4dCkge1xuICB2YXIgaW5wdXQgPSBhcm1vci5kZWNvZGUoYXJtb3JlZFRleHQpO1xuICBpZiAoaW5wdXQudHlwZSAhPT0gZW51bXMuYXJtb3Iuc2lnbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2UuJyk7XG4gIH1cbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5yZWFkKGlucHV0LmRhdGEpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBDbGVhcnRleHRNZXNzYWdlKGlucHV0LnRleHQsIHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3TWVzc2FnZTtcbn1cblxuZXhwb3J0cy5DbGVhcnRleHRNZXNzYWdlID0gQ2xlYXJ0ZXh0TWVzc2FnZTtcbmV4cG9ydHMucmVhZEFybW9yZWQgPSByZWFkQXJtb3JlZDtcbiIsIkpYRyA9IHtcbiAgZXhpc3RzOiAoZnVuY3Rpb24odW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHYpIHtcbiAgICAgIHJldHVybiAhKHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsKTtcbiAgICB9XG4gIH0pKClcbn07XG5KWEcuZGVjb21wcmVzcyA9IGZ1bmN0aW9uKHN0cikge1xuICByZXR1cm4gdW5lc2NhcGUoKG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShzdHIpKSkudW56aXAoKVswXVswXSk7XG59O1xuLypcbiAgICBDb3B5cmlnaHQgMjAwOC0yMDEyXG4gICAgICAgIE1hdHRoaWFzIEVobWFubixcbiAgICAgICAgTWljaGFlbCBHZXJoYWV1c2VyLFxuICAgICAgICBDYXJzdGVuIE1pbGxlcixcbiAgICAgICAgQmlhbmNhIFZhbGVudGluLFxuICAgICAgICBBbGZyZWQgV2Fzc2VybWFubixcbiAgICAgICAgUGV0ZXIgV2lsZmFocnRcblxuICAgIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEpTWEdyYXBoLlxuICAgIFxuICAgIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlIFZlcnNpb24gMi4wLCBvciBMR1BMIFZlcnNpb24gMyBsaWNlbnNlcy5cblxuICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICAgIGFsb25nIHdpdGggSlNYQ29tcHJlc3Nvci4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAgICBcbiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBBcGFjaGUgTGljZW5zZSBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICBcbiAgICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLz4uXG5cbiovXG5cbi8qKlxuICogQGNsYXNzIFV0aWwgY2xhc3NcbiAqIEBjbGFzc2Rlc2MgVXRpbGl0aWVzIGZvciB1bmNvbXByZXNzaW5nIGFuZCBiYXNlNjQgZGVjb2RpbmdcbiAqIENsYXNzIGZvciBndW56aXBwaW5nLCB1bnppcHBpbmcgYW5kIGJhc2U2NCBkZWNvZGluZyBvZiBmaWxlcy5cbiAqIEl0IGlzIHVzZWQgZm9yIHJlYWRpbmcgR0VPTkV4VCwgR2VvZ2VicmEgYW5kIEludGVyZ2VvIGZpbGVzLlxuICpcbiAqIE9ubHkgSHVmZm1hbiBjb2RlcyBhcmUgZGVjb2RlZCBpbiBndW56aXAuXG4gKiBUaGUgY29kZSBpcyBiYXNlZCBvbiB0aGUgc291cmNlIGNvZGUgZm9yIGd1bnppcC5jIGJ5IFBhc2kgT2phbGEgXG4gKiB7QGxpbmsgaHR0cDovL3d3dy5jcy50dXQuZmkvfmFsYmVydC9EZXYvZ3VuemlwL2d1bnppcC5jfVxuICoge0BsaW5rIGh0dHA6Ly93d3cuY3MudHV0LmZpL35hbGJlcnR9XG4gKi9cbkpYRy5VdGlsID0ge307XG5cbi8qKlxuICogVW56aXAgemlwIGZpbGVzXG4gKi9cbkpYRy5VdGlsLlVuemlwID0gZnVuY3Rpb24oYmFycmF5KSB7XG4gIHZhciBvdXRwdXRBcnIgPSBbXSxcbiAgICBvdXRwdXQgPSBcIlwiLFxuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZ3BmbGFncyxcbiAgICBmaWxlcyA9IDAsXG4gICAgdW56aXBwZWQgPSBbXSxcbiAgICBjcmMsXG4gICAgYnVmMzJrID0gbmV3IEFycmF5KDMyNzY4KSxcbiAgICBiSWR4ID0gMCxcbiAgICBtb2RlWklQID0gZmFsc2UsXG5cbiAgICBDUkMsIFNJWkUsXG5cbiAgICBiaXRSZXZlcnNlID0gW1xuICAgICAgICAweDAwLCAweDgwLCAweDQwLCAweGMwLCAweDIwLCAweGEwLCAweDYwLCAweGUwLFxuICAgICAgICAweDEwLCAweDkwLCAweDUwLCAweGQwLCAweDMwLCAweGIwLCAweDcwLCAweGYwLFxuICAgICAgICAweDA4LCAweDg4LCAweDQ4LCAweGM4LCAweDI4LCAweGE4LCAweDY4LCAweGU4LFxuICAgICAgICAweDE4LCAweDk4LCAweDU4LCAweGQ4LCAweDM4LCAweGI4LCAweDc4LCAweGY4LFxuICAgICAgICAweDA0LCAweDg0LCAweDQ0LCAweGM0LCAweDI0LCAweGE0LCAweDY0LCAweGU0LFxuICAgICAgICAweDE0LCAweDk0LCAweDU0LCAweGQ0LCAweDM0LCAweGI0LCAweDc0LCAweGY0LFxuICAgICAgICAweDBjLCAweDhjLCAweDRjLCAweGNjLCAweDJjLCAweGFjLCAweDZjLCAweGVjLFxuICAgICAgICAweDFjLCAweDljLCAweDVjLCAweGRjLCAweDNjLCAweGJjLCAweDdjLCAweGZjLFxuICAgICAgICAweDAyLCAweDgyLCAweDQyLCAweGMyLCAweDIyLCAweGEyLCAweDYyLCAweGUyLFxuICAgICAgICAweDEyLCAweDkyLCAweDUyLCAweGQyLCAweDMyLCAweGIyLCAweDcyLCAweGYyLFxuICAgICAgICAweDBhLCAweDhhLCAweDRhLCAweGNhLCAweDJhLCAweGFhLCAweDZhLCAweGVhLFxuICAgICAgICAweDFhLCAweDlhLCAweDVhLCAweGRhLCAweDNhLCAweGJhLCAweDdhLCAweGZhLFxuICAgICAgICAweDA2LCAweDg2LCAweDQ2LCAweGM2LCAweDI2LCAweGE2LCAweDY2LCAweGU2LFxuICAgICAgICAweDE2LCAweDk2LCAweDU2LCAweGQ2LCAweDM2LCAweGI2LCAweDc2LCAweGY2LFxuICAgICAgICAweDBlLCAweDhlLCAweDRlLCAweGNlLCAweDJlLCAweGFlLCAweDZlLCAweGVlLFxuICAgICAgICAweDFlLCAweDllLCAweDVlLCAweGRlLCAweDNlLCAweGJlLCAweDdlLCAweGZlLFxuICAgICAgICAweDAxLCAweDgxLCAweDQxLCAweGMxLCAweDIxLCAweGExLCAweDYxLCAweGUxLFxuICAgICAgICAweDExLCAweDkxLCAweDUxLCAweGQxLCAweDMxLCAweGIxLCAweDcxLCAweGYxLFxuICAgICAgICAweDA5LCAweDg5LCAweDQ5LCAweGM5LCAweDI5LCAweGE5LCAweDY5LCAweGU5LFxuICAgICAgICAweDE5LCAweDk5LCAweDU5LCAweGQ5LCAweDM5LCAweGI5LCAweDc5LCAweGY5LFxuICAgICAgICAweDA1LCAweDg1LCAweDQ1LCAweGM1LCAweDI1LCAweGE1LCAweDY1LCAweGU1LFxuICAgICAgICAweDE1LCAweDk1LCAweDU1LCAweGQ1LCAweDM1LCAweGI1LCAweDc1LCAweGY1LFxuICAgICAgICAweDBkLCAweDhkLCAweDRkLCAweGNkLCAweDJkLCAweGFkLCAweDZkLCAweGVkLFxuICAgICAgICAweDFkLCAweDlkLCAweDVkLCAweGRkLCAweDNkLCAweGJkLCAweDdkLCAweGZkLFxuICAgICAgICAweDAzLCAweDgzLCAweDQzLCAweGMzLCAweDIzLCAweGEzLCAweDYzLCAweGUzLFxuICAgICAgICAweDEzLCAweDkzLCAweDUzLCAweGQzLCAweDMzLCAweGIzLCAweDczLCAweGYzLFxuICAgICAgICAweDBiLCAweDhiLCAweDRiLCAweGNiLCAweDJiLCAweGFiLCAweDZiLCAweGViLFxuICAgICAgICAweDFiLCAweDliLCAweDViLCAweGRiLCAweDNiLCAweGJiLCAweDdiLCAweGZiLFxuICAgICAgICAweDA3LCAweDg3LCAweDQ3LCAweGM3LCAweDI3LCAweGE3LCAweDY3LCAweGU3LFxuICAgICAgICAweDE3LCAweDk3LCAweDU3LCAweGQ3LCAweDM3LCAweGI3LCAweDc3LCAweGY3LFxuICAgICAgICAweDBmLCAweDhmLCAweDRmLCAweGNmLCAweDJmLCAweGFmLCAweDZmLCAweGVmLFxuICAgICAgICAweDFmLCAweDlmLCAweDVmLCAweGRmLCAweDNmLCAweGJmLCAweDdmLCAweGZmXG4gICAgXSxcblxuICAgIGNwbGVucyA9IFtcbiAgICAgICAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSxcbiAgICAgICAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDBcbiAgICBdLFxuXG4gICAgY3BsZXh0ID0gW1xuICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAyLCAyLCAyLCAyLFxuICAgICAgICAzLCAzLCAzLCAzLCA0LCA0LCA0LCA0LCA1LCA1LCA1LCA1LCAwLCA5OSwgOTlcbiAgICBdLFxuICAgIC8qIDk5PT1pbnZhbGlkICovXG5cbiAgICBjcGRpc3QgPSBbXG4gICAgICAgIDB4MDAwMSwgMHgwMDAyLCAweDAwMDMsIDB4MDAwNCwgMHgwMDA1LCAweDAwMDcsIDB4MDAwOSwgMHgwMDBkLFxuICAgICAgICAweDAwMTEsIDB4MDAxOSwgMHgwMDIxLCAweDAwMzEsIDB4MDA0MSwgMHgwMDYxLCAweDAwODEsIDB4MDBjMSxcbiAgICAgICAgMHgwMTAxLCAweDAxODEsIDB4MDIwMSwgMHgwMzAxLCAweDA0MDEsIDB4MDYwMSwgMHgwODAxLCAweDBjMDEsXG4gICAgICAgIDB4MTAwMSwgMHgxODAxLCAweDIwMDEsIDB4MzAwMSwgMHg0MDAxLCAweDYwMDFcbiAgICBdLFxuXG4gICAgY3BkZXh0ID0gW1xuICAgICAgICAwLCAwLCAwLCAwLCAxLCAxLCAyLCAyLFxuICAgICAgICAzLCAzLCA0LCA0LCA1LCA1LCA2LCA2LFxuICAgICAgICA3LCA3LCA4LCA4LCA5LCA5LCAxMCwgMTAsXG4gICAgICAgIDExLCAxMSwgMTIsIDEyLCAxMywgMTNcbiAgICBdLFxuXG4gICAgYm9yZGVyID0gWzE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTVdLFxuXG4gICAgYkEgPSBiYXJyYXksXG5cbiAgICBieXRlcG9zID0gMCxcbiAgICBiaXRwb3MgPSAwLFxuICAgIGJiID0gMSxcbiAgICBiaXRzID0gMCxcblxuICAgIE5BTUVNQVggPSAyNTYsXG5cbiAgICBuYW1lQnVmID0gW10sXG5cbiAgICBmaWxlb3V0O1xuXG4gIGZ1bmN0aW9uIHJlYWRCeXRlKCkge1xuICAgIGJpdHMgKz0gODtcbiAgICBpZiAoYnl0ZXBvcyA8IGJBLmxlbmd0aCkge1xuICAgICAgLy9pZiAoZGVidWcpXG4gICAgICAvLyAgICBkb2N1bWVudC53cml0ZShieXRlcG9zK1wiOiBcIitiQVtieXRlcG9zXStcIjxicj5cIik7XG4gICAgICByZXR1cm4gYkFbYnl0ZXBvcysrXTtcbiAgICB9IGVsc2VcbiAgICAgIHJldHVybiAtMTtcbiAgfTtcblxuICBmdW5jdGlvbiBieXRlQWxpZ24oKSB7XG4gICAgYmIgPSAxO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlYWRCaXQoKSB7XG4gICAgdmFyIGNhcnJ5O1xuICAgIGJpdHMrKztcbiAgICBjYXJyeSA9IChiYiAmIDEpO1xuICAgIGJiID4+PSAxO1xuICAgIGlmIChiYiA9PSAwKSB7XG4gICAgICBiYiA9IHJlYWRCeXRlKCk7XG4gICAgICBjYXJyeSA9IChiYiAmIDEpO1xuICAgICAgYmIgPSAoYmIgPj4gMSkgfCAweDgwO1xuICAgIH1cbiAgICByZXR1cm4gY2Fycnk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVhZEJpdHMoYSkge1xuICAgIHZhciByZXMgPSAwLFxuICAgICAgaSA9IGE7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICByZXMgPSAocmVzIDw8IDEpIHwgcmVhZEJpdCgpO1xuICAgIH1cbiAgICBpZiAoYSkge1xuICAgICAgcmVzID0gYml0UmV2ZXJzZVtyZXNdID4+ICg4IC0gYSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgZnVuY3Rpb24gZmx1c2hCdWZmZXIoKSB7XG4gICAgLy9kb2N1bWVudC53cml0ZSgnRkxVU0hCVUZGRVI6JytidWYzMmspO1xuICAgIGJJZHggPSAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGFkZEJ1ZmZlcihhKSB7XG4gICAgU0laRSsrO1xuICAgIC8vQ1JDPXVwZGNyYyhhLGNyYyk7XG4gICAgYnVmMzJrW2JJZHgrK10gPSBhO1xuICAgIG91dHB1dEFyci5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYSkpO1xuICAgIC8vb3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGEpO1xuICAgIGlmIChiSWR4ID09IDB4ODAwMCkge1xuICAgICAgLy9kb2N1bWVudC53cml0ZSgnQUREQlVGRkVSOicrYnVmMzJrKTtcbiAgICAgIGJJZHggPSAwO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBIdWZOb2RlKCkge1xuICAgIHRoaXMuYjAgPSAwO1xuICAgIHRoaXMuYjEgPSAwO1xuICAgIHRoaXMuanVtcCA9IG51bGw7XG4gICAgdGhpcy5qdW1wcG9zID0gLTE7XG4gIH07XG5cbiAgdmFyIExJVEVSQUxTID0gMjg4O1xuXG4gIHZhciBsaXRlcmFsVHJlZSA9IG5ldyBBcnJheShMSVRFUkFMUyk7XG4gIHZhciBkaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoMzIpO1xuICB2YXIgdHJlZXBvcyA9IDA7XG4gIHZhciBQbGFjZXMgPSBudWxsO1xuICB2YXIgUGxhY2VzMiA9IG51bGw7XG5cbiAgdmFyIGltcERpc3RhbmNlVHJlZSA9IG5ldyBBcnJheSg2NCk7XG4gIHZhciBpbXBMZW5ndGhUcmVlID0gbmV3IEFycmF5KDY0KTtcblxuICB2YXIgbGVuID0gMDtcbiAgdmFyIGZwb3MgPSBuZXcgQXJyYXkoMTcpO1xuICBmcG9zWzBdID0gMDtcbiAgdmFyIGZsZW5zO1xuICB2YXIgZm1heDtcblxuICBmdW5jdGlvbiBJc1BhdCgpIHtcbiAgICB3aGlsZSAoMSkge1xuICAgICAgaWYgKGZwb3NbbGVuXSA+PSBmbWF4KVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICBpZiAoZmxlbnNbZnBvc1tsZW5dXSA9PSBsZW4pXG4gICAgICAgIHJldHVybiBmcG9zW2xlbl0rKztcbiAgICAgIGZwb3NbbGVuXSsrO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBSZWMoKSB7XG4gICAgdmFyIGN1cnBsYWNlID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgIHZhciB0bXA7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bGVuOlwiICsgbGVuICsgXCIgdHJlZXBvczpcIiArIHRyZWVwb3MpO1xuICAgIGlmIChsZW4gPT0gMTcpIHsgLy93YXIgMTdcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgdHJlZXBvcysrO1xuICAgIGxlbisrO1xuXG4gICAgdG1wID0gSXNQYXQoKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBkb2N1bWVudC53cml0ZShcIjxicj5Jc1BhdCBcIiArIHRtcCk7XG4gICAgaWYgKHRtcCA+PSAwKSB7XG4gICAgICBjdXJwbGFjZS5iMCA9IHRtcDsgLyogbGVhZiBjZWxsIGZvciAwLWJpdCAqL1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMCBcIiArIGN1cnBsYWNlLmIwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm90IGEgTGVhZiBjZWxsICovXG4gICAgICBjdXJwbGFjZS5iMCA9IDB4ODAwMDtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjAgXCIgKyBjdXJwbGFjZS5iMCk7XG4gICAgICBpZiAoUmVjKCkpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgdG1wID0gSXNQYXQoKTtcbiAgICBpZiAodG1wID49IDApIHtcbiAgICAgIGN1cnBsYWNlLmIxID0gdG1wOyAvKiBsZWFmIGNlbGwgZm9yIDEtYml0ICovXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIxIFwiICsgY3VycGxhY2UuYjEpO1xuICAgICAgY3VycGxhY2UuanVtcCA9IG51bGw7IC8qIEp1c3QgZm9yIHRoZSBkaXNwbGF5IHJvdXRpbmUgKi9cbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm90IGEgTGVhZiBjZWxsICovXG4gICAgICBjdXJwbGFjZS5iMSA9IDB4ODAwMDtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjEgXCIgKyBjdXJwbGFjZS5iMSk7XG4gICAgICBjdXJwbGFjZS5qdW1wID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgICAgY3VycGxhY2UuanVtcHBvcyA9IHRyZWVwb3M7XG4gICAgICBpZiAoUmVjKCkpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgbGVuLS07XG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgZnVuY3Rpb24gQ3JlYXRlVHJlZShjdXJyZW50VHJlZSwgbnVtdmFsLCBsZW5ndGhzLCBzaG93KSB7XG4gICAgdmFyIGk7XG4gICAgLyogQ3JlYXRlIHRoZSBIdWZmbWFuIGRlY29kZSB0cmVlL3RhYmxlICovXG4gICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5jcmVhdGV0cmVlPGJyPlwiKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBkb2N1bWVudC53cml0ZShcImN1cnJlbnRUcmVlIFwiICsgY3VycmVudFRyZWUgKyBcIiBudW12YWwgXCIgKyBudW12YWwgKyBcIiBsZW5ndGhzIFwiICsgbGVuZ3RocyArIFwiIHNob3cgXCIgKyBzaG93KTtcbiAgICBQbGFjZXMgPSBjdXJyZW50VHJlZTtcbiAgICB0cmVlcG9zID0gMDtcbiAgICBmbGVucyA9IGxlbmd0aHM7XG4gICAgZm1heCA9IG51bXZhbDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTc7IGkrKylcbiAgICAgIGZwb3NbaV0gPSAwO1xuICAgIGxlbiA9IDA7XG4gICAgaWYgKFJlYygpKSB7XG4gICAgICAvL2ZwcmludGYoc3RkZXJyLCBcImludmFsaWQgaHVmZm1hbiB0cmVlXFxuXCIpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcImludmFsaWQgaHVmZm1hbiB0cmVlXFxuXCIpO1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIGRvY3VtZW50LndyaXRlKCc8YnI+VHJlZTogJyArIFBsYWNlcy5sZW5ndGgpO1xuICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCAzMjsgYSsrKSB7XG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiUGxhY2VzW1wiICsgYSArIFwiXS5iMD1cIiArIFBsYWNlc1thXS5iMCArIFwiPGJyPlwiKTtcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJQbGFjZXNbXCIgKyBhICsgXCJdLmIxPVwiICsgUGxhY2VzW2FdLmIxICsgXCI8YnI+XCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qaWYoc2hvdykge1xuICAgICAgICAgICAgdmFyIHRtcDtcbiAgICAgICAgICAgIGZvcih0bXA9Y3VycmVudFRyZWU7dG1wPFBsYWNlczt0bXArKykge1xuICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIjB4JTAzeCAgMHglMDN4ICgweCUwNHgpXCIsdG1wLWN1cnJlbnRUcmVlLCB0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjAsKHRtcC0+anVtcD90bXAtPmp1bXAtY3VycmVudFRyZWU6MCkqNisweGNmMCk7XG4gICAgICAgICAgICAgICAgaWYoISh0bXAuYjAgJiAweDgwMDApKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vZnByaW50ZihzdGRvdXQsIFwiICAweCUwM3ggKCVjKVwiLCB0bXAtPmIwLCh0bXAtPmIwPDI1NiAmJiBpc3ByaW50KHRtcC0+YjApKT90bXAtPmIwOifvv70nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYoISh0bXAuYjEgJiAweDgwMDApKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKCh0bXAuYjAgJiAweDgwMDApKVxuICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIFwiICAgICAgICAgICBcIik7XG4gICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIiAgMHglMDN4ICglYylcIiwgdG1wLT5iMSwodG1wLT5iMTwyNTYgJiYgaXNwcmludCh0bXAtPmIxKSk/dG1wLT5iMTon77+9Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIlxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSovXG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgZnVuY3Rpb24gRGVjb2RlVmFsdWUoY3VycmVudFRyZWUpIHtcbiAgICB2YXIgbGVuLCBpLFxuICAgICAgeHRyZWVwb3MgPSAwLFxuICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXSxcbiAgICAgIGI7XG5cbiAgICAvKiBkZWNvZGUgb25lIHN5bWJvbCBvZiB0aGUgZGF0YSAqL1xuICAgIHdoaWxlICgxKSB7XG4gICAgICBiID0gcmVhZEJpdCgpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcImI9XCIgKyBiKTtcbiAgICAgIGlmIChiKSB7XG4gICAgICAgIGlmICghKFguYjEgJiAweDgwMDApKSB7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJyZXQxXCIpO1xuICAgICAgICAgIHJldHVybiBYLmIxOyAvKiBJZiBsZWFmIG5vZGUsIHJldHVybiBkYXRhICovXG4gICAgICAgIH1cbiAgICAgICAgWCA9IFguanVtcDtcbiAgICAgICAgbGVuID0gY3VycmVudFRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICBpZiAoY3VycmVudFRyZWVbaV0gPT09IFgpIHtcbiAgICAgICAgICAgIHh0cmVlcG9zID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL3h0cmVlcG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIShYLmIwICYgMHg4MDAwKSkge1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwicmV0MlwiKTtcbiAgICAgICAgICByZXR1cm4gWC5iMDsgLyogSWYgbGVhZiBub2RlLCByZXR1cm4gZGF0YSAqL1xuICAgICAgICB9XG4gICAgICAgIC8vWCsrOyAvLz8/Pz8/Pz8/Pz8/Pz8/Pz8/P1xuICAgICAgICB4dHJlZXBvcysrO1xuICAgICAgICBYID0gY3VycmVudFRyZWVbeHRyZWVwb3NdO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBEZWZsYXRlTG9vcCgpIHtcbiAgICB2YXIgbGFzdCwgYywgdHlwZSwgaSwgbGVuO1xuXG4gICAgZG8ge1xuICAgICAgLyppZigobGFzdCA9IHJlYWRCaXQoKSkpe1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIk5vdCBMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0qL1xuICAgICAgbGFzdCA9IHJlYWRCaXQoKTtcbiAgICAgIHR5cGUgPSByZWFkQml0cygyKTtcbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJTdG9yZWRcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIkZpeGVkIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIkR5bmFtaWMgSHVmZm1hbiBjb2Rlc1xcblwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiUmVzZXJ2ZWQgYmxvY2sgdHlwZSEhXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiVW5leHBlY3RlZCB2YWx1ZSAlZCFcXG5cIiwgdHlwZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlID09IDApIHtcbiAgICAgICAgdmFyIGJsb2NrTGVuLCBjU3VtO1xuXG4gICAgICAgIC8vIFN0b3JlZCBcbiAgICAgICAgYnl0ZUFsaWduKCk7XG4gICAgICAgIGJsb2NrTGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgYmxvY2tMZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgY1N1bSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNTdW0gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgaWYgKCgoYmxvY2tMZW4gXiB+Y1N1bSkgJiAweGZmZmYpKSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJCbG9ja0xlbiBjaGVja3N1bSBtaXNtYXRjaFxcblwiKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYmxvY2tMZW4tLSkge1xuICAgICAgICAgIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlID09IDEpIHtcbiAgICAgICAgdmFyIGo7XG5cbiAgICAgICAgLyogRml4ZWQgSHVmZm1hbiB0YWJsZXMgLS0gZml4ZWQgZGVjb2RlIHJvdXRpbmUgKi9cbiAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgIDI1NiAgICAwMDAwMDAwICAgICAgICAwXG4gICAgICAgICAgICAgICAgOiAgIDogICAgIDpcbiAgICAgICAgICAgICAgICAyNzkgICAgMDAxMDExMSAgICAgICAgMjNcbiAgICAgICAgICAgICAgICAwICAgMDAxMTAwMDAgICAgNDhcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMTQzICAgIDEwMTExMTExICAgIDE5MVxuICAgICAgICAgICAgICAgIDI4MCAxMTAwMDAwMCAgICAxOTJcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMjg3IDExMDAwMTExICAgIDE5OVxuICAgICAgICAgICAgICAgIDE0NCAgICAxMTAwMTAwMDAgICAgNDAwXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgIDpcbiAgICAgICAgICAgICAgICAyNTUgICAgMTExMTExMTExICAgIDUxMVxuICAgIFxuICAgICAgICAgICAgICAgIE5vdGUgdGhlIGJpdCBvcmRlciFcbiAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgaiA9IChiaXRSZXZlcnNlW3JlYWRCaXRzKDcpXSA+PiAxKTtcbiAgICAgICAgICBpZiAoaiA+IDIzKSB7XG4gICAgICAgICAgICBqID0gKGogPDwgMSkgfCByZWFkQml0KCk7IC8qIDQ4Li4yNTUgKi9cblxuICAgICAgICAgICAgaWYgKGogPiAxOTkpIHsgLyogMjAwLi4yNTUgKi9cbiAgICAgICAgICAgICAgaiAtPSAxMjg7IC8qICA3Mi4uMTI3ICovXG4gICAgICAgICAgICAgIGogPSAoaiA8PCAxKSB8IHJlYWRCaXQoKTsgLyogMTQ0Li4yNTUgPDwgKi9cbiAgICAgICAgICAgIH0gZWxzZSB7IC8qICA0OC4uMTk5ICovXG4gICAgICAgICAgICAgIGogLT0gNDg7IC8qICAgMC4uMTUxICovXG4gICAgICAgICAgICAgIGlmIChqID4gMTQzKSB7XG4gICAgICAgICAgICAgICAgaiA9IGogKyAxMzY7IC8qIDI4MC4uMjg3IDw8ICovXG4gICAgICAgICAgICAgICAgLyogICAwLi4xNDMgPDwgKi9cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7IC8qICAgMC4uMjMgKi9cbiAgICAgICAgICAgIGogKz0gMjU2OyAvKiAyNTYuLjI3OSA8PCAqL1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaiA8IDI1Nikge1xuICAgICAgICAgICAgYWRkQnVmZmVyKGopO1xuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIm91dDpcIitTdHJpbmcuZnJvbUNoYXJDb2RlKGopKTtcbiAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgXCJAJWQgJTAyeFxcblwiLCBTSVpFLCBqKTsqL1xuICAgICAgICAgIH0gZWxzZSBpZiAoaiA9PSAyNTYpIHtcbiAgICAgICAgICAgIC8qIEVPRiAqL1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7XG5cbiAgICAgICAgICAgIGogLT0gMjU2ICsgMTsgLyogYnl0ZXMgKyBFT0YgKi9cbiAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07XG5cbiAgICAgICAgICAgIGogPSBiaXRSZXZlcnNlW3JlYWRCaXRzKDUpXSA+PiAzO1xuICAgICAgICAgICAgaWYgKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKDgpO1xuICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0gLSA4KSA8PCA4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyhjcGRleHRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG5cbiAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgXCJAJWQgKGwlMDJ4LGQlMDR4KVxcblwiLCBTSVpFLCBsZW4sIGRpc3QpOyovXG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGVuOyBqKyspIHtcbiAgICAgICAgICAgICAgdmFyIGMgPSBidWYzMmtbKGJJZHggLSBkaXN0KSAmIDB4N2ZmZl07XG4gICAgICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gd2hpbGVcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSAyKSB7XG4gICAgICAgIHZhciBqLCBuLCBsaXRlcmFsQ29kZXMsIGRpc3RDb2RlcywgbGVuQ29kZXM7XG4gICAgICAgIHZhciBsbCA9IG5ldyBBcnJheSgyODggKyAzMik7IC8vIFwic3RhdGljXCIganVzdCB0byBwcmVzZXJ2ZSBzdGFja1xuXG4gICAgICAgIC8vIER5bmFtaWMgSHVmZm1hbiB0YWJsZXMgXG5cbiAgICAgICAgbGl0ZXJhbENvZGVzID0gMjU3ICsgcmVhZEJpdHMoNSk7XG4gICAgICAgIGRpc3RDb2RlcyA9IDEgKyByZWFkQml0cyg1KTtcbiAgICAgICAgbGVuQ29kZXMgPSA0ICsgcmVhZEJpdHMoNCk7XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+cGFyYW06IFwiK2xpdGVyYWxDb2RlcytcIiBcIitkaXN0Q29kZXMrXCIgXCIrbGVuQ29kZXMrXCI8YnI+XCIpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgMTk7IGorKykge1xuICAgICAgICAgIGxsW2pdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgZGVjb2RlIHRyZWUgY29kZSBsZW5ndGhzXG5cbiAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5cIik7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBsZW5Db2RlczsgaisrKSB7XG4gICAgICAgICAgbGxbYm9yZGVyW2pdXSA9IHJlYWRCaXRzKDMpO1xuICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUobGxbYm9yZGVyW2pdXStcIiBcIik7XG4gICAgICAgIH1cbiAgICAgICAgLy9mcHJpbnRmKGVycmZwLCBcIlxcblwiKTtcbiAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPGJyPmxsOicrbGwpO1xuICAgICAgICBsZW4gPSBkaXN0YW5jZVRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgZGlzdGFuY2VUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgaWYgKENyZWF0ZVRyZWUoZGlzdGFuY2VUcmVlLCAxOSwgbGwsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5kaXN0YW5jZVRyZWVcIik7XG4gICAgICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCBkaXN0YW5jZVRyZWUubGVuZ3RoOyBhKyspIHtcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPlwiICsgZGlzdGFuY2VUcmVlW2FdLmIwICsgXCIgXCIgKyBkaXN0YW5jZVRyZWVbYV0uYjEgKyBcIiBcIiArIGRpc3RhbmNlVHJlZVthXS5qdW1wICsgXCIgXCIgK1xuICAgICAgICAgICAgICBkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyk7XG4gICAgICAgICAgICAvKmlmIChkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyE9LTEpXG4gICAgICAgICAgICAgICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjArXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjEpO1xuICAgICAgICAgICAgICAgIFx0Ki9cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPEJSPnRyZWUgY3JlYXRlZCcpO1xuXG4gICAgICAgIC8vcmVhZCBpbiBsaXRlcmFsIGFuZCBkaXN0YW5jZSBjb2RlIGxlbmd0aHNcbiAgICAgICAgbiA9IGxpdGVyYWxDb2RlcyArIGRpc3RDb2RlcztcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHZhciB6ID0gLTE7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5uPVwiICsgbiArIFwiIGJpdHM6IFwiICsgYml0cyArIFwiPGJyPlwiKTtcbiAgICAgICAgd2hpbGUgKGkgPCBuKSB7XG4gICAgICAgICAgeisrO1xuICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPlwiICsgeiArIFwiIGk6XCIgKyBpICsgXCIgZGVjb2RlOiBcIiArIGogKyBcIiAgICBiaXRzIFwiICsgYml0cyArIFwiPGJyPlwiKTtcbiAgICAgICAgICBpZiAoaiA8IDE2KSB7IC8vIGxlbmd0aCBvZiBjb2RlIGluIGJpdHMgKDAuLjE1KVxuICAgICAgICAgICAgbGxbaSsrXSA9IGo7XG4gICAgICAgICAgfSBlbHNlIGlmIChqID09IDE2KSB7IC8vIHJlcGVhdCBsYXN0IGxlbmd0aCAzIHRvIDYgdGltZXMgXG4gICAgICAgICAgICB2YXIgbDtcbiAgICAgICAgICAgIGogPSAzICsgcmVhZEJpdHMoMik7XG4gICAgICAgICAgICBpZiAoaSArIGogPiBuKSB7XG4gICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbCA9IGkgPyBsbFtpIC0gMV0gOiAwO1xuICAgICAgICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICAgICAgICBsbFtpKytdID0gbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGogPT0gMTcpIHsgLy8gMyB0byAxMCB6ZXJvIGxlbmd0aCBjb2Rlc1xuICAgICAgICAgICAgICBqID0gMyArIHJlYWRCaXRzKDMpO1xuICAgICAgICAgICAgfSBlbHNlIHsgLy8gaiA9PSAxODogMTEgdG8gMTM4IHplcm8gbGVuZ3RoIGNvZGVzIFxuICAgICAgICAgICAgICBqID0gMTEgKyByZWFkQml0cyg3KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpICsgaiA+IG4pIHtcbiAgICAgICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAoai0tKSB7XG4gICAgICAgICAgICAgIGxsW2krK10gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKmZvcihqPTA7IGo8bGl0ZXJhbENvZGVzK2Rpc3RDb2RlczsgaisrKSB7XG4gICAgICAgICAgICAgICAgLy9mcHJpbnRmKGVycmZwLCBcIiVkIFwiLCBsbFtqXSk7XG4gICAgICAgICAgICAgICAgaWYgKChqJjcpPT03KVxuICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsIFwiXFxuXCIpOyovXG4gICAgICAgIC8vIENhbiBvdmVyd3JpdGUgdHJlZSBkZWNvZGUgdHJlZSBhcyBpdCBpcyBub3QgdXNlZCBhbnltb3JlXG4gICAgICAgIGxlbiA9IGxpdGVyYWxUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGxpdGVyYWxUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgaWYgKENyZWF0ZVRyZWUobGl0ZXJhbFRyZWUsIGxpdGVyYWxDb2RlcywgbGwsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBkaXN0YW5jZVRyZWVbaV0gPSBuZXcgSHVmTm9kZSgpO1xuICAgICAgICB2YXIgbGwyID0gbmV3IEFycmF5KCk7XG4gICAgICAgIGZvciAoaSA9IGxpdGVyYWxDb2RlczsgaSA8IGxsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbGwyW2kgLSBsaXRlcmFsQ29kZXNdID0gbGxbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKENyZWF0ZVRyZWUoZGlzdGFuY2VUcmVlLCBkaXN0Q29kZXMsIGxsMiwgMCkpIHtcbiAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5saXRlcmFsVHJlZVwiKTtcbiAgICAgICAgb3V0ZXI6IHdoaWxlICgxKSB7XG4gICAgICAgICAgaiA9IERlY29kZVZhbHVlKGxpdGVyYWxUcmVlKTtcbiAgICAgICAgICBpZiAoaiA+PSAyNTYpIHsgLy8gSW4gQzY0OiBpZiBjYXJyeSBzZXRcbiAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7XG4gICAgICAgICAgICBqIC09IDI1NjtcbiAgICAgICAgICAgIGlmIChqID09IDApIHtcbiAgICAgICAgICAgICAgLy8gRU9GXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgbGVuID0gcmVhZEJpdHMoY3BsZXh0W2pdKSArIGNwbGVuc1tqXTtcblxuICAgICAgICAgICAgaiA9IERlY29kZVZhbHVlKGRpc3RhbmNlVHJlZSk7XG4gICAgICAgICAgICBpZiAoY3BkZXh0W2pdID4gOCkge1xuICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoOCk7XG4gICAgICAgICAgICAgIGRpc3QgfD0gKHJlYWRCaXRzKGNwZGV4dFtqXSAtIDgpIDw8IDgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKGNwZGV4dFtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXN0ICs9IGNwZGlzdFtqXTtcbiAgICAgICAgICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgICAgICAgICBpZiAoYklkeCAtIGRpc3QgPCAwKSB7XG4gICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIGMgPSBidWYzMmtbKGJJZHggLSBkaXN0KSAmIDB4N2ZmZl07XG4gICAgICAgICAgICAgIGFkZEJ1ZmZlcihjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkQnVmZmVyKGopO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gd2hpbGUgKCFsYXN0KTtcbiAgICBmbHVzaEJ1ZmZlcigpO1xuXG4gICAgYnl0ZUFsaWduKCk7XG4gICAgcmV0dXJuIDA7XG4gIH07XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwRmlsZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgaTtcbiAgICB0aGlzLnVuemlwKCk7XG4gICAgLy9hbGVydCh1bnppcHBlZFswXVsxXSk7XG4gICAgZm9yIChpID0gMDsgaSA8IHVuemlwcGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodW56aXBwZWRbaV1bMV0gPT0gbmFtZSkge1xuICAgICAgICByZXR1cm4gdW56aXBwZWRbaV1bMF07XG4gICAgICB9XG4gICAgfVxuXG4gIH07XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLmRlZmxhdGUgPSBmdW5jdGlvbigpIHtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIERlZmxhdGVMb29wKCk7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiREVGTEFURVwiO1xuICAgIGZpbGVzKys7XG4gICAgcmV0dXJuIHVuemlwcGVkO1xuICB9XG5cbiAgSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwID0gZnVuY3Rpb24oKSB7XG4gICAgLy9jb252ZXJ0VG9CeXRlQXJyYXkoaW5wdXQpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KGJBKTtcbiAgICAvKmZvciAoaT0wO2k8YkEubGVuZ3RoKjg7aSsrKXtcblx0XHRkb2N1bWVudC53cml0ZShyZWFkQml0KCkpO1xuXHRcdGlmICgoaSsxKSU4PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIpO1xuXHR9Ki9cbiAgICAvKmZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJ5dGUoKStcIiBcIik7XG5cdFx0aWYgKChpKzEpJTg9PTApXG5cdFx0XHRkb2N1bWVudC53cml0ZShcIiBcIik7XG5cdH1cblx0Zm9yIChpPTA7aTxiQS5sZW5ndGg7aSsrKXtcblx0XHRkb2N1bWVudC53cml0ZShiQVtpXStcIiBcIik7XG5cdFx0aWYgKChpKzEpJTE2PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIpO1xuXHR9XHRcblx0Ki9cbiAgICAvL2FsZXJ0KGJBKTtcbiAgICBuZXh0RmlsZSgpO1xuICAgIHJldHVybiB1bnppcHBlZDtcbiAgfTtcblxuICBmdW5jdGlvbiBuZXh0RmlsZSgpIHtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChcIk5FWFRGSUxFXCIpO1xuICAgIG91dHB1dEFyciA9IFtdO1xuICAgIHZhciB0bXAgPSBbXTtcbiAgICBtb2RlWklQID0gZmFsc2U7XG4gICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICB0bXBbMV0gPSByZWFkQnl0ZSgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KFwidHlwZTogXCIgKyB0bXBbMF0gKyBcIiBcIiArIHRtcFsxXSk7XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjc4XCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCJkYVwiLCAxNikpIHsgLy9HWklQXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiR0VPTkV4VC1HWklQXCIpO1xuICAgICAgRGVmbGF0ZUxvb3AoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiZ2VvbmV4dC5neHRcIjtcbiAgICAgIGZpbGVzKys7XG4gICAgfVxuICAgIGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLCAxNikgJiYgdG1wWzFdID09IHBhcnNlSW50KFwiOWNcIiwgMTYpKSB7IC8vWkxJQlxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIlpMSUJcIik7XG4gICAgICBEZWZsYXRlTG9vcCgpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzFdID0gXCJaTElCXCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiMWZcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjhiXCIsIDE2KSkgeyAvL0daSVBcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJHWklQXCIpO1xuICAgICAgLy9EZWZsYXRlTG9vcCgpO1xuICAgICAgc2tpcGRpcigpO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgdW56aXBwZWRbZmlsZXNdWzFdID0gXCJmaWxlXCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNTBcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsIDE2KSkgeyAvL1pJUFxuICAgICAgbW9kZVpJUCA9IHRydWU7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzNdID0gcmVhZEJ5dGUoKTtcbiAgICAgIGlmICh0bXBbMl0gPT0gcGFyc2VJbnQoXCIzXCIsIDE2KSAmJiB0bXBbM10gPT0gcGFyc2VJbnQoXCI0XCIsIDE2KSkge1xuICAgICAgICAvL01PREVfWklQXG4gICAgICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIHRtcFsxXSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcIlpJUC1WZXJzaW9uOiBcIiArIHRtcFsxXSArIFwiIFwiICsgdG1wWzBdIC8gMTAgKyBcIi5cIiArIHRtcFswXSAlIDEwKTtcblxuICAgICAgICBncGZsYWdzID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZ3BmbGFncyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwiZ3BmbGFnczogXCIgKyBncGZsYWdzKTtcblxuICAgICAgICB2YXIgbWV0aG9kID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgbWV0aG9kIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJtZXRob2Q6IFwiICsgbWV0aG9kKTtcblxuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuICAgICAgICByZWFkQnl0ZSgpO1xuXG4gICAgICAgIHZhciBjcmMgPSByZWFkQnl0ZSgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgICAgdmFyIGNvbXBTaXplID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIHZhciBzaXplID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcImxvY2FsIENSQzogXCIgKyBjcmMgKyBcIlxcbmxvY2FsIFNpemU6IFwiICsgc2l6ZSArIFwiXFxubG9jYWwgQ29tcFNpemU6IFwiICsgY29tcFNpemUpO1xuXG4gICAgICAgIHZhciBmaWxlbGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZmlsZWxlbiB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcblxuICAgICAgICB2YXIgZXh0cmFsZW4gPSByZWFkQnl0ZSgpO1xuICAgICAgICBleHRyYWxlbiB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcblxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJmaWxlbGVuIFwiICsgZmlsZWxlbik7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICBuYW1lQnVmID0gW107XG4gICAgICAgIHdoaWxlIChmaWxlbGVuLS0pIHtcbiAgICAgICAgICB2YXIgYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgICAgaWYgKGMgPT0gXCIvXCIgfCBjID09IFwiOlwiKSB7XG4gICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGkgPCBOQU1FTUFYIC0gMSlcbiAgICAgICAgICAgIG5hbWVCdWZbaSsrXSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwibmFtZUJ1ZjogXCIgKyBuYW1lQnVmKTtcblxuICAgICAgICAvL25hbWVCdWZbaV0gPSBcIlxcMFwiO1xuICAgICAgICBpZiAoIWZpbGVvdXQpXG4gICAgICAgICAgZmlsZW91dCA9IG5hbWVCdWY7XG5cbiAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IGV4dHJhbGVuKSB7XG4gICAgICAgICAgYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgQ1JDID0gMHhmZmZmZmZmZjtcbiAgICAgICAgU0laRSA9IDA7XG5cbiAgICAgICAgaWYgKHNpemUgPT0gMCAmJiBmaWxlT3V0LmNoYXJBdChmaWxlb3V0Lmxlbmd0aCAtIDEpID09IFwiL1wiKSB7XG4gICAgICAgICAgLy9za2lwZGlyXG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJza2lwZGlyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRob2QgPT0gOCkge1xuICAgICAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IG5hbWVCdWYuam9pbignJyk7XG4gICAgICAgICAgZmlsZXMrKztcbiAgICAgICAgICAvL3JldHVybiBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcGRpcigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBza2lwZGlyKCkge1xuICAgIHZhciBjcmMsXG4gICAgICB0bXAgPSBbXSxcbiAgICAgIGNvbXBTaXplLCBzaXplLCBvcywgaSwgYztcblxuICAgIGlmICgoZ3BmbGFncyAmIDgpKSB7XG4gICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFsyXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbM10gPSByZWFkQnl0ZSgpO1xuXG4gICAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNTBcIiwgMTYpICYmXG4gICAgICAgIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsIDE2KSAmJlxuICAgICAgICB0bXBbMl0gPT0gcGFyc2VJbnQoXCIwN1wiLCAxNikgJiZcbiAgICAgICAgdG1wWzNdID09IHBhcnNlSW50KFwiMDhcIiwgMTYpKSB7XG4gICAgICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNyYyA9IHRtcFswXSB8ICh0bXBbMV0gPDwgOCkgfCAodG1wWzJdIDw8IDE2KSB8ICh0bXBbM10gPDwgMjQpO1xuICAgICAgfVxuXG4gICAgICBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkNSQzpcIik7XG4gICAgfVxuXG4gICAgaWYgKG1vZGVaSVApXG4gICAgICBuZXh0RmlsZSgpO1xuXG4gICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAodG1wWzBdICE9IDgpIHtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCFcIik7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBncGZsYWdzID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIGlmICgoZ3BmbGFncyAmIH4ocGFyc2VJbnQoXCIxZlwiLCAxNikpKSlcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGZsYWdzIHNldCFcIik7XG4gICAgfVxuXG4gICAgcmVhZEJ5dGUoKTtcbiAgICByZWFkQnl0ZSgpO1xuICAgIHJlYWRCeXRlKCk7XG4gICAgcmVhZEJ5dGUoKTtcblxuICAgIHJlYWRCeXRlKCk7XG4gICAgb3MgPSByZWFkQnl0ZSgpO1xuXG4gICAgaWYgKChncGZsYWdzICYgNCkpIHtcbiAgICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgbGVuID0gdG1wWzBdICsgMjU2ICogdG1wWzFdO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkV4dHJhIGZpZWxkIHNpemU6IFwiICsgbGVuKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiA4KSkge1xuICAgICAgaSA9IDA7XG4gICAgICBuYW1lQnVmID0gW107XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgaWYgKGMgPT0gXCI3XCIgfHwgYyA9PSBcIjpcIilcbiAgICAgICAgICBpID0gMDtcbiAgICAgICAgaWYgKGkgPCBOQU1FTUFYIC0gMSlcbiAgICAgICAgICBuYW1lQnVmW2krK10gPSBjO1xuICAgICAgfVxuICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJvcmlnaW5hbCBmaWxlIG5hbWU6IFwiICsgbmFtZUJ1Zik7XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgMTYpKSB7XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgLy9GSUxFIENPTU1FTlRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiAyKSkge1xuICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgIHJlYWRCeXRlKCk7XG4gICAgfVxuXG4gICAgRGVmbGF0ZUxvb3AoKTtcblxuICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgIHNpemUgPSByZWFkQnl0ZSgpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICBpZiAobW9kZVpJUClcbiAgICAgIG5leHRGaWxlKCk7XG5cbiAgfTtcblxufTtcblxuLyoqXG4gKiAgQmFzZTY0IGVuY29kaW5nIC8gZGVjb2RpbmdcbiAqICB7QGxpbmsgaHR0cDovL3d3dy53ZWJ0b29sa2l0LmluZm8vfVxuICovXG5KWEcuVXRpbC5CYXNlNjQgPSB7XG5cbiAgLy8gcHJpdmF0ZSBwcm9wZXJ0eVxuICBfa2V5U3RyOiBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCIsXG5cbiAgLy8gcHVibGljIG1ldGhvZCBmb3IgZW5jb2RpbmdcbiAgZW5jb2RlOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgIGNocjEsIGNocjIsIGNocjMsIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsXG4gICAgICBpID0gMDtcblxuICAgIGlucHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2VuY29kZShpbnB1dCk7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBjaHIxID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuICAgICAgY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGNocjMgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgIGVuYzEgPSBjaHIxID4+IDI7XG4gICAgICBlbmMyID0gKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KTtcbiAgICAgIGVuYzMgPSAoKGNocjIgJiAxNSkgPDwgMikgfCAoY2hyMyA+PiA2KTtcbiAgICAgIGVuYzQgPSBjaHIzICYgNjM7XG5cbiAgICAgIGlmIChpc05hTihjaHIyKSkge1xuICAgICAgICBlbmMzID0gZW5jNCA9IDY0O1xuICAgICAgfSBlbHNlIGlmIChpc05hTihjaHIzKSkge1xuICAgICAgICBlbmM0ID0gNjQ7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dC5wdXNoKFt0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzEpLFxuICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMiksXG4gICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMzKSxcbiAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzQpXG4gICAgICBdLmpvaW4oJycpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0LmpvaW4oJycpO1xuICB9LFxuXG4gIC8vIHB1YmxpYyBtZXRob2QgZm9yIGRlY29kaW5nXG4gIGRlY29kZTogZnVuY3Rpb24oaW5wdXQsIHV0ZjgpIHtcbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBjaHIxLCBjaHIyLCBjaHIzLFxuICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNCxcbiAgICAgIGkgPSAwO1xuXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgXCJcIik7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBlbmMxID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzMgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmM0ID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuXG4gICAgICBjaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTtcbiAgICAgIGNocjIgPSAoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKTtcbiAgICAgIGNocjMgPSAoKGVuYzMgJiAzKSA8PCA2KSB8IGVuYzQ7XG5cbiAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSkpO1xuXG4gICAgICBpZiAoZW5jMyAhPSA2NCkge1xuICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjIpKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmM0ICE9IDY0KSB7XG4gICAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dCA9IG91dHB1dC5qb2luKCcnKTtcblxuICAgIGlmICh1dGY4KSB7XG4gICAgICBvdXRwdXQgPSBKWEcuVXRpbC5CYXNlNjQuX3V0ZjhfZGVjb2RlKG91dHB1dCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG5cbiAgfSxcblxuICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZW5jb2RpbmdcbiAgX3V0ZjhfZW5jb2RlOiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpO1xuICAgIHZhciB1dGZ0ZXh0ID0gXCJcIjtcblxuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgc3RyaW5nLmxlbmd0aDsgbisrKSB7XG5cbiAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQobik7XG5cbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgIH0gZWxzZSBpZiAoKGMgPiAxMjcpICYmIChjIDwgMjA0OCkpIHtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDYpIHwgMTkyKTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiAxMikgfCAyMjQpO1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChjID4+IDYpICYgNjMpIHwgMTI4KTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB1dGZ0ZXh0O1xuICB9LFxuXG4gIC8vIHByaXZhdGUgbWV0aG9kIGZvciBVVEYtOCBkZWNvZGluZ1xuICBfdXRmOF9kZWNvZGU6IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgICB2YXIgc3RyaW5nID0gW10sXG4gICAgICBpID0gMCxcbiAgICAgIGMgPSAwLFxuICAgICAgYzIgPSAwLFxuICAgICAgYzMgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCB1dGZ0ZXh0Lmxlbmd0aCkge1xuICAgICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYykpO1xuICAgICAgICBpKys7XG4gICAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpO1xuICAgICAgICBpICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAxNSkgPDwgMTIpIHwgKChjMiAmIDYzKSA8PCA2KSB8IChjMyAmIDYzKSkpO1xuICAgICAgICBpICs9IDM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdHJpbmcuam9pbignJyk7XG4gIH0sXG5cbiAgX2Rlc3RyaXA6IGZ1bmN0aW9uKHN0cmlwcGVkLCB3cmFwKSB7XG4gICAgdmFyIGxpbmVzID0gW10sXG4gICAgICBsaW5lbm8sIGksXG4gICAgICBkZXN0cmlwcGVkID0gW107XG5cbiAgICBpZiAod3JhcCA9PSBudWxsKVxuICAgICAgd3JhcCA9IDc2O1xuXG4gICAgc3RyaXBwZWQucmVwbGFjZSgvIC9nLCBcIlwiKTtcbiAgICBsaW5lbm8gPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lbm87IGkrKylcbiAgICAgIGxpbmVzW2ldID0gc3RyaXBwZWQuc3Vic3RyKGkgKiB3cmFwLCB3cmFwKTtcbiAgICBpZiAobGluZW5vICE9IHN0cmlwcGVkLmxlbmd0aCAvIHdyYXApXG4gICAgICBsaW5lc1tsaW5lcy5sZW5ndGhdID0gc3RyaXBwZWQuc3Vic3RyKGxpbmVubyAqIHdyYXAsIHN0cmlwcGVkLmxlbmd0aCAtIChsaW5lbm8gKiB3cmFwKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspXG4gICAgICBkZXN0cmlwcGVkLnB1c2gobGluZXNbaV0pO1xuICAgIHJldHVybiBkZXN0cmlwcGVkLmpvaW4oJ1xcbicpO1xuICB9LFxuXG4gIGRlY29kZUFzQXJyYXk6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgdmFyIGRlYyA9IHRoaXMuZGVjb2RlKGlucHV0KSxcbiAgICAgIGFyID0gW10sXG4gICAgICBpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBkZWMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFyW2ldID0gZGVjLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBhcjtcbiAgfSxcblxuICBkZWNvZGVHRU9ORXhUOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHJldHVybiBkZWNvZGVBc0FycmF5KGRlc3RyaXAoaW5wdXQpLCBmYWxzZSk7XG4gIH1cbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuSlhHLlV0aWwuYXNjaWlDaGFyQ29kZUF0ID0gZnVuY3Rpb24oc3RyLCBpKSB7XG4gIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gIGlmIChjID4gMjU1KSB7XG4gICAgc3dpdGNoIChjKSB7XG4gICAgICBjYXNlIDgzNjQ6XG4gICAgICAgIGMgPSAxMjg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjE4OlxuICAgICAgICBjID0gMTMwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDAyOlxuICAgICAgICBjID0gMTMxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMjpcbiAgICAgICAgYyA9IDEzMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMzA6XG4gICAgICAgIGMgPSAxMzM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjI0OlxuICAgICAgICBjID0gMTM0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyNTpcbiAgICAgICAgYyA9IDEzNTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDcxMDpcbiAgICAgICAgYyA9IDEzNjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyNDA6XG4gICAgICAgIGMgPSAxMzc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTI6XG4gICAgICAgIGMgPSAxMzg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjQ5OlxuICAgICAgICBjID0gMTM5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM4OlxuICAgICAgICBjID0gMTQwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgxOlxuICAgICAgICBjID0gMTQyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxNjpcbiAgICAgICAgYyA9IDE0NTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTc6XG4gICAgICAgIGMgPSAxNDY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjIwOlxuICAgICAgICBjID0gMTQ3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMTpcbiAgICAgICAgYyA9IDE0ODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjY6XG4gICAgICAgIGMgPSAxNDk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjExOlxuICAgICAgICBjID0gMTUwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxMjpcbiAgICAgICAgYyA9IDE1MTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDczMjpcbiAgICAgICAgYyA9IDE1MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDg0ODI6XG4gICAgICAgIGMgPSAxNTM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTM6XG4gICAgICAgIGMgPSAxNTQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjUwOlxuICAgICAgICBjID0gMTU1O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM5OlxuICAgICAgICBjID0gMTU2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgyOlxuICAgICAgICBjID0gMTU4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzc2OlxuICAgICAgICBjID0gMTU5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYztcbn07XG5cbi8qKlxuICogRGVjb2Rpbmcgc3RyaW5nIGludG8gdXRmLThcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHV0ZjggZGVjb2RlZCBzdHJpbmdcbiAqL1xuSlhHLlV0aWwudXRmOERlY29kZSA9IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgdmFyIHN0cmluZyA9IFtdO1xuICB2YXIgaSA9IDA7XG4gIHZhciBjID0gMCxcbiAgICBjMSA9IDAsXG4gICAgYzIgPSAwLFxuICAgIGMzO1xuICBpZiAoIUpYRy5leGlzdHModXRmdGV4dCkpIHJldHVybiAnJztcblxuICB3aGlsZSAoaSA8IHV0ZnRleHQubGVuZ3RoKSB7XG4gICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgIGkrKztcbiAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMzEpIDw8IDYpIHwgKGMyICYgNjMpKSk7XG4gICAgICBpICs9IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgIGkgKz0gMztcbiAgICB9XG4gIH07XG4gIHJldHVybiBzdHJpbmcuam9pbignJyk7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgcmFuZG9tIHV1aWQuXG4gKiBodHRwOi8vd3d3LmJyb29mYS5jb21cbiAqIG1haWx0bzpyb2JlcnRAYnJvb2ZhLmNvbVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMCBSb2JlcnQgS2llZmZlclxuICogRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGFuZCBHUEwgbGljZW5zZXMuXG4gKlxuICogRVhBTVBMRVM6XG4gKiAgID4+PiBNYXRoLnV1aWQoKVxuICogICBcIjkyMzI5RDM5LTZGNUMtNDUyMC1BQkZDLUFBQjY0NTQ0RTE3MlwiXG4gKi9cbkpYRy5VdGlsLmdlblVVSUQgPSBmdW5jdGlvbigpIHtcbiAgLy8gUHJpdmF0ZSBhcnJheSBvZiBjaGFycyB0byB1c2VcbiAgdmFyIGNoYXJzID0gJzAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Jy5zcGxpdCgnJyksXG4gICAgdXVpZCA9IG5ldyBBcnJheSgzNiksXG4gICAgcm5kID0gMCxcbiAgICByO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzY7IGkrKykge1xuICAgIGlmIChpID09IDggfHwgaSA9PSAxMyB8fCBpID09IDE4IHx8IGkgPT0gMjMpIHtcbiAgICAgIHV1aWRbaV0gPSAnLSc7XG4gICAgfSBlbHNlIGlmIChpID09IDE0KSB7XG4gICAgICB1dWlkW2ldID0gJzQnO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocm5kIDw9IDB4MDIpIHJuZCA9IDB4MjAwMDAwMCArIChNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwKSB8IDA7XG4gICAgICByID0gcm5kICYgMHhmO1xuICAgICAgcm5kID0gcm5kID4+IDQ7XG4gICAgICB1dWlkW2ldID0gY2hhcnNbKGkgPT0gMTkpID8gKHIgJiAweDMpIHwgMHg4IDogcl07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHV1aWQuam9pbignJyk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gSlhHO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgY29uZmlnL2NvbmZpZyAqL1xuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqXG4gKiBUaGlzIG9iamVjdCBjb250YWlucyBjb25maWd1cmF0aW9uIHZhbHVlcyBhbmQgaW1wbGVtZW50c1xuICogc3RvcmluZyBhbmQgcmV0cmlldmluZyBjb25maWd1cmF0aW9uIHRoZW0gZnJvbSBIVE1MNSBsb2NhbCBzdG9yYWdlLlxuICpcbiAqIFRoaXMgb2JqZWN0IGNhbiBiZSBhY2Nlc3NlZCBhZnRlciBjYWxsaW5nIG9wZW5wZ3AuaW5pdCgpXG4gKiB1c2luZyBvcGVucGdwLmNvbmZpZ1xuICogU3RvcmVkIGNvbmZpZyBwYXJhbWV0ZXJzIGNhbiBiZSBhY2Nlc3NlZCB1c2luZ1xuICogb3BlbnBncC5jb25maWcuY29uZmlnXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIEdQRzRCcm93c2VycyBjb25maWcgb2JqZWN0XG4gKi9cbnZhciBjb25maWcgPSBmdW5jdGlvbigpIHtcbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gcHJlZmVyX2hhc2hfYWxnb3JpdGhtXG4gICAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gZW5jcnlwdGlvbl9jaXBoZXJcbiAgICogQHByb3BlcnR5IHtJbnRlZ2VyfSBjb21wcmVzc2lvblxuICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IHNob3dfdmVyc2lvblxuICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IHNob3dfY29tbWVudFxuICAgKiBAcHJvcGVydHkge0Jvb2xlYW59IGludGVncml0eV9wcm90ZWN0XG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBrZXlzZXJ2ZXJcbiAgICovXG4gIHRoaXMucHJlZmVyX2hhc2hfYWxnb3JpdGhtID0gZW51bXMuaGFzaC5zaGEyNTY7XG4gIHRoaXMuZW5jcnlwdGlvbl9jaXBoZXIgPSBlbnVtcy5zeW1tZXRyaWMuYWVzMjU2O1xuICB0aGlzLmNvbXByZXNzaW9uID0gZW51bXMuY29tcHJlc3Npb24uemlwO1xuICB0aGlzLnNob3dfdmVyc2lvbiA9IHRydWU7XG4gIHRoaXMuc2hvd19jb21tZW50ID0gdHJ1ZTtcbiAgdGhpcy5pbnRlZ3JpdHlfcHJvdGVjdCA9IHRydWU7XG4gIHRoaXMua2V5c2VydmVyID0gXCJrZXlzZXJ2ZXIubGludXguaXRcIjsgLy8gXCJwZ3AubWl0LmVkdToxMTM3MVwiXG5cbiAgdGhpcy52ZXJzaW9uc3RyaW5nID0gXCJPcGVuUEdQLmpzIFZFUlNJT05cIjtcbiAgdGhpcy5jb21tZW50c3RyaW5nID0gXCJodHRwOi8vb3BlbnBncGpzLm9yZ1wiO1xuXG4gIC8qKlxuICAgKiBJZiBlbmFibGVkLCBkZWJ1ZyBtZXNzYWdlcyB3aWxsIGJlIHByaW50ZWRcbiAgICovXG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgY29uZmlnKCk7XG4iLCIvLyBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggXG5cbi8vIG1vZGlmaWVkIHZlcnNpb24gb2YgaHR0cDovL3d3dy5oYW5ld2luLm5ldC9lbmNyeXB0L1BHZGVjb2RlLmpzOlxuXG4vKiBPcGVuUEdQIGVuY3J5cHRpb24gdXNpbmcgUlNBL0FFU1xuICogQ29weXJpZ2h0IDIwMDUtMjAwNiBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlXG4gKiB2ZXJzaW9uIDIuMCwgY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvblxuXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIFxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3JcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XG4gKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgXG4gKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0XG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlclxuICogbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi5cbiAqL1xuXG4vKiogQG1vZHVsZSBjcnlwdG8vY2ZiICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjaXBoZXIgPSByZXF1aXJlKCcuL2NpcGhlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAvKipcbiAgICogQW4gYXJyYXkgb2YgYnl0ZXMsIHRoYXQgaXMgaW50ZWdlcnMgd2l0aCB2YWx1ZXMgZnJvbSAwIHRvIDI1NVxuICAgKiBAdHlwZWRlZiB7KEFycmF5fFVpbnQ4QXJyYXkpfSBvcGVucGdwX2J5dGVfYXJyYXlcbiAgICovXG5cbiAgLyoqXG4gICAqIEJsb2NrIGNpcGhlciBmdW5jdGlvblxuICAgKiBAY2FsbGJhY2sgb3BlbnBncF9ibG9ja19jaXBoZXJfZm5cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGJsb2NrIEEgYmxvY2sgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkgdG8gdXNlIGluIGVuY3J5cHRpb24vZGVjcnlwdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX2J5dGVfYXJyYXl9IEVuY3J5cHRlZC9kZWNyeXB0ZWQgYmxvY2tcbiAgICovXG5cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBlbmNyeXB0cyBhIGdpdmVuIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXhyYW5kb20gXG4gICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgYmxvY2tjaXBoZXIgdG8gZW5jcnlwdCBhIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeHJhbmRvbSByYW5kb20gYnl0ZXMgb2YgYmxvY2tfc2l6ZSBsZW5ndGggcHJvdmlkZWQgXG4gICAqICBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGluIHByZWZpeGluZyB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfYmxvY2tfY2lwaGVyX2ZufSBibG9ja2NpcGhlcmZuIHRoZSBhbGdvcml0aG0gZW5jcnlwdCBmdW5jdGlvbiB0byBlbmNyeXB0XG4gICAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24uIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgdGhlIGJsb2NrIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGFsZ29yaXRobSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwbGFpbnRleHQgZGF0YSB0byBiZSBlbmNyeXB0ZWQgcHJvdmlkZWQgYXMgYSBzdHJpbmdcbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBrZXkgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhLiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBcbiAgICogIGJsb2NrY2lwaGVyZm5cbiAgICogQHBhcmFtIHtCb29sZWFufSByZXN5bmMgYSBib29sZWFuIHZhbHVlIHNwZWNpZnlpbmcgaWYgYSByZXN5bmMgb2YgdGhlIFxuICAgKiAgSVYgc2hvdWxkIGJlIHVzZWQgb3Igbm90LiBUaGUgZW5jcnlwdGVkZGF0YXBhY2tldCB1c2VzIHRoZSBcbiAgICogIFwib2xkXCIgc3R5bGUgd2l0aCBhIHJlc3luYy4gRW5jcnlwdGlvbiB3aXRoaW4gYW4gXG4gICAqICBlbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhIHBhY2tldCBpcyBub3QgcmVzeW5jaW5nIHRoZSBJVi5cbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyB3aXRoIHRoZSBlbmNyeXB0ZWQgZGF0YVxuICAgKi9cbiAgZW5jcnlwdDogZnVuY3Rpb24ocHJlZml4cmFuZG9tLCBjaXBoZXJmbiwgcGxhaW50ZXh0LCBrZXksIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBGUiA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgRlJFID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuXG4gICAgcHJlZml4cmFuZG9tID0gcHJlZml4cmFuZG9tICsgcHJlZml4cmFuZG9tLmNoYXJBdChibG9ja19zaXplIC0gMikgKyBwcmVmaXhyYW5kb20uY2hhckF0KGJsb2NrX3NpemUgLSAxKTtcbiAgICB1dGlsLnByaW50X2RlYnVnKFwicHJlZml4cmFuZG9tOlwiICsgdXRpbC5oZXhzdHJkdW1wKHByZWZpeHJhbmRvbSkpO1xuICAgIHZhciBjaXBoZXJ0ZXh0ID0gXCJcIjtcbiAgICAvLyAxLiAgVGhlIGZlZWRiYWNrIHJlZ2lzdGVyIChGUikgaXMgc2V0IHRvIHRoZSBJViwgd2hpY2ggaXMgYWxsIHplcm9zLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IDA7XG5cbiAgICAvLyAyLiAgRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFIChGUiBFbmNyeXB0ZWQpLiAgVGhpcyBpcyB0aGVcbiAgICAvLyAgICAgZW5jcnlwdGlvbiBvZiBhbiBhbGwtemVybyB2YWx1ZS5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcbiAgICAvLyAzLiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IEJTIG9jdGV0cyBvZiByYW5kb20gZGF0YSBwcmVmaXhlZCB0b1xuICAgIC8vICAgICB0aGUgcGxhaW50ZXh0IHRvIHByb2R1Y2UgQ1sxXSB0aHJvdWdoIENbQlNdLCB0aGUgZmlyc3QgQlMgb2N0ZXRzXG4gICAgLy8gICAgIG9mIGNpcGhlcnRleHQuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChpKSk7XG5cbiAgICAvLyA0LiAgRlIgaXMgbG9hZGVkIHdpdGggQ1sxXSB0aHJvdWdoIENbQlNdLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIC8vIDUuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUsIHRoZSBlbmNyeXB0aW9uIG9mIHRoZSBmaXJzdCBCU1xuICAgIC8vIFx0ICAgb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAvLyA2LiAgVGhlIGxlZnQgdHdvIG9jdGV0cyBvZiBGUkUgZ2V0IHhvcmVkIHdpdGggdGhlIG5leHQgdHdvIG9jdGV0cyBvZlxuICAgIC8vICAgICBkYXRhIHRoYXQgd2VyZSBwcmVmaXhlZCB0byB0aGUgcGxhaW50ZXh0LiAgVGhpcyBwcm9kdWNlcyBDW0JTKzFdXG4gICAgLy8gICAgIGFuZCBDW0JTKzJdLCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVswXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKTtcbiAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzFdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDcuICAoVGhlIHJlc3luYyBzdGVwKSBGUiBpcyBsb2FkZWQgd2l0aCBDMy1DMTAuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIC8vIDguICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUiwga2V5KTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKylcbiAgICAgICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemUgKyAyOyBuIDwgcGxhaW50ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIC8vIDEwLiBGUiBpcyBsb2FkZWQgd2l0aCBDMTEtQzE4XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuICsgaSk7XG5cbiAgICAgICAgLy8gMTEuIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cbiAgICAgICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAgICAgLy8gMTIuIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBuZXh0IDggb2N0ZXRzIG9mIHBsYWludGV4dCwgdG8gcHJvZHVjZSB0aGVcbiAgICAgICAgLy8gbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoKG4gLSAyKSArXG4gICAgICAgICAgICBpKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBsYWludGV4dCA9IFwiICBcIiArIHBsYWludGV4dDtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGJsb2NrX3NpemU7IGkrKykgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIHZhciB0ZW1wQ2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIDIgKiBibG9ja19zaXplKS5zcGxpdCgnJyk7XG4gICAgICB2YXIgdGVtcENpcGhlcnRleHRTdHJpbmcgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZyhibG9ja19zaXplKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBwbGFpbnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gdGVtcENpcGhlcnRleHRTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgICAgdGVtcENpcGhlcnRleHRTdHJpbmcgPSAnJztcblxuICAgICAgICAvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuICAgICAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgICAgICAvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZVxuICAgICAgICAvLyAgICAgbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gICAgIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgdGhlIHBsYWludGV4dCBpcyB1c2VkIHVwLlxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgICAgIHRlbXBDaXBoZXJ0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdChuICsgaSkpKTtcbiAgICAgICAgICB0ZW1wQ2lwaGVydGV4dFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4gKyBpKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNpcGhlcnRleHQgPSB0ZW1wQ2lwaGVydGV4dC5qb2luKCcnKTtcblxuICAgIH1cblxuICAgIGNpcGhlcnRleHQgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZygwLCBwbGFpbnRleHQubGVuZ3RoICsgMiArIGJsb2NrX3NpemUpO1xuXG4gICAgcmV0dXJuIGNpcGhlcnRleHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcmVmaXhlZCBkYXRhIGZvciB0aGUgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlIChNREMpIGNvbXB1dGF0aW9uXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ibG9ja19jaXBoZXJfZm59IGNpcGhlcmZuLmVuY3J5cHQgQ2lwaGVyIGZ1bmN0aW9uIHRvIHVzZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgQmxvY2tzaXplIG9mIHRoZSBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBUaGUga2V5IGZvciBlbmNyeXB0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBlbmNyeXB0ZWQgZGF0YVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHBsYWludGV4dCBEYXRhIG9mIEQoY2lwaGVydGV4dCkgd2l0aCBibG9ja3NpemUgbGVuZ3RoICsyXG4gICAqL1xuICBtZGM6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQpIHtcbiAgICBjaXBoZXJmbiA9IG5ldyBjaXBoZXJbY2lwaGVyZm5dKGtleSk7XG4gICAgdmFyIGJsb2NrX3NpemUgPSBjaXBoZXJmbi5ibG9ja1NpemU7XG5cbiAgICB2YXIgaWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBhYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGk7XG5cblxuICAgIC8vIGluaXRpYWxpc2F0aW9uIHZlY3RvclxuICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IDA7XG5cbiAgICBpYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jayk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgYWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWJsb2NrW2ldIF49IGFibG9ja1tpXTtcbiAgICB9XG5cbiAgICBhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGFibG9jayk7XG5cbiAgICByZXR1cm4gdXRpbC5iaW4yc3RyKGlibG9jaykgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbMF0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSkpICtcbiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzFdIF4gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUgKyAxKSk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGRlY3J5cHRzIGEgZ2l2ZW4gcGxhaW50ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWRcbiAgICogYmxvY2tjaXBoZXIgdG8gZGVjcnlwdCBhIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtvcGVucGdwX2Jsb2NrX2NpcGhlcl9mbn0gYmxvY2tjaXBoZXJmbiBUaGUgYWxnb3JpdGhtIF9lbmNyeXB0XyBmdW5jdGlvbiB0byBlbmNyeXB0XG4gICAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSB0aGUgYmxvY2sgc2l6ZSBpbiBieXRlcyBvZiB0aGUgYWxnb3JpdGhtIHVzZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBsYWludGV4dCBjaXBoZXJ0ZXh0IHRvIGJlIGRlY3J5cHRlZCBwcm92aWRlZCBhcyBhIHN0cmluZ1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IGtleSB0byBiZSB1c2VkIHRvIGRlY3J5cHQgdGhlIGNpcGhlcnRleHQuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIFxuICAgKiAgYmxvY2tjaXBoZXJmblxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3luYyBhIGJvb2xlYW4gdmFsdWUgc3BlY2lmeWluZyBpZiBhIHJlc3luYyBvZiB0aGUgXG4gICAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIFxuICAgKiAgXCJvbGRcIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBEZWNyeXB0aW9uIHdpdGhpbiBhbiBcbiAgICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHdpdGggdGhlIHBsYWludGV4dCBkYXRhXG4gICAqL1xuXG4gIGRlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgaSwgbiA9ICcnO1xuICAgIHZhciB0ZXh0ID0gW107XG5cbiAgICAvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3JcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwO1xuXG4gICAgaWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2ssIGtleSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgYWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWJsb2NrW2ldIF49IGFibG9ja1tpXTtcbiAgICB9XG5cbiAgICBhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGFibG9jaywga2V5KTtcblxuICAgIC8vIHRlc3QgY2hlY2sgb2N0ZXRzXG4gICAgaWYgKGlibG9ja1tibG9ja19zaXplIC0gMl0gIT0gKGFibG9ja1swXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkgfHwgaWJsb2NrW2Jsb2NrX3NpemUgLSAxXSAhPSAoYWJsb2NrW1xuICAgICAgMV0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEuJyk7XG4gICAgfVxuXG4gICAgLyogIFJGQzQ4ODA6IFRhZyAxOCBhbmQgUmVzeW5jOlxuXHRcdCAqICBbLi4uXSBVbmxpa2UgdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCBub1xuXHRcdCAqICBzcGVjaWFsIENGQiByZXN5bmNocm9uaXphdGlvbiBpcyBkb25lIGFmdGVyIGVuY3J5cHRpbmcgdGhpcyBwcmVmaXhcblx0XHQgKiAgZGF0YS4gIFNlZSBcIk9wZW5QR1AgQ0ZCIE1vZGVcIiBiZWxvdyBmb3IgbW9yZSBkZXRhaWxzLlxuXG5cdFx0ICovXG5cbiAgICBpZiAocmVzeW5jKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZSArIDI7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZSAmJiBpICsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobiArIGkpO1xuICAgICAgICAgIHRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1tpXSBeIGlibG9ja1tpXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemUgJiYgaSArIG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4gKyBpKTtcbiAgICAgICAgICB0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbaV0gXiBpYmxvY2tbaV0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuID0gcmVzeW5jID8gMCA6IDI7XG5cbiAgICB0ZXh0ID0gdGV4dC5qb2luKCcnKTtcblxuICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhuLCBjaXBoZXJ0ZXh0Lmxlbmd0aCAtIGJsb2NrX3NpemUgLSAyICsgbik7XG5cblxuICAgIHJldHVybiB0ZXh0O1xuICB9LFxuXG5cbiAgbm9ybWFsRW5jcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgcGxhaW50ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja2kgPSBcIlwiO1xuICAgIHZhciBibG9ja2MgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBjeXBoZXJ0ZXh0ID0gW107XG4gICAgdmFyIHRlbXBCbG9jayA9IFtdO1xuICAgIGJsb2NrYyA9IGl2LnN1YnN0cmluZygwLCBibG9ja19zaXplKTtcbiAgICB3aGlsZSAocGxhaW50ZXh0Lmxlbmd0aCA+IGJsb2NrX3NpemUgKiBwb3MpIHtcbiAgICAgIHZhciBlbmNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrYykpO1xuICAgICAgYmxvY2tpID0gcGxhaW50ZXh0LnN1YnN0cmluZygocG9zICogYmxvY2tfc2l6ZSksIChwb3MgKiBibG9ja19zaXplKSArIGJsb2NrX3NpemUpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja2kubGVuZ3RoOyBpKyspXG4gICAgICAgIHRlbXBCbG9jay5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2tpLmNoYXJDb2RlQXQoaSkgXiBlbmNibG9ja1tpXSkpO1xuICAgICAgYmxvY2tjID0gdGVtcEJsb2NrLmpvaW4oJycpO1xuICAgICAgdGVtcEJsb2NrID0gW107XG4gICAgICBjeXBoZXJ0ZXh0LnB1c2goYmxvY2tjKTtcbiAgICAgIHBvcysrO1xuICAgIH1cbiAgICByZXR1cm4gY3lwaGVydGV4dC5qb2luKCcnKTtcbiAgfSxcblxuICBub3JtYWxEZWNyeXB0OiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBjaXBoZXJ0ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja3AgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBwbGFpbnRleHQgPSBbXTtcbiAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICBpZiAoaXYgPT0gbnVsbClcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBibG9ja3AgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICBlbHNlXG4gICAgICBibG9ja3AgPSBpdi5zdWJzdHJpbmcoMCwgYmxvY2tfc2l6ZSk7XG4gICAgd2hpbGUgKGNpcGhlcnRleHQubGVuZ3RoID4gKGJsb2NrX3NpemUgKiBwb3MpKSB7XG4gICAgICB2YXIgZGVjYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KHV0aWwuc3RyMmJpbihibG9ja3ApKTtcbiAgICAgIGJsb2NrcCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKChwb3MgKiAoYmxvY2tfc2l6ZSkpICsgb2Zmc2V0LCAocG9zICogKGJsb2NrX3NpemUpKSArIChibG9ja19zaXplKSArIG9mZnNldCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBwbGFpbnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJsb2NrcC5jaGFyQ29kZUF0KGkpIF4gZGVjYmxvY2tbaV0pKTtcbiAgICAgIH1cbiAgICAgIHBvcysrO1xuICAgIH1cblxuICAgIHJldHVybiBwbGFpbnRleHQuam9pbignJyk7XG4gIH1cbn1cbiIsIi8qIFJpam5kYWVsIChBRVMpIEVuY3J5cHRpb25cbiAqIENvcHlyaWdodCAyMDA1IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMS4xLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvclxuICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnlcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcbiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3RcbiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyXG4gKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxuICovXG5cbi8qKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvYWVzICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBUaGUgcm91bmQgY29uc3RhbnRzIHVzZWQgaW4gc3Via2V5IGV4cGFuc2lvblxudmFyIFJjb24gPSBbXG4gICAgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNiwgMHg2YywgMHhkOCxcbiAgICAweGFiLCAweDRkLCAweDlhLCAweDJmLCAweDVlLCAweGJjLCAweDYzLCAweGM2LCAweDk3LCAweDM1LCAweDZhLCAweGQ0LFxuICAgIDB4YjMsIDB4N2QsIDB4ZmEsIDB4ZWYsIDB4YzUsIDB4OTFcbl07XG5cbi8vIFByZWNvbXB1dGVkIGxvb2t1cCB0YWJsZSBmb3IgdGhlIFNCb3hcbnZhciBTID0gW1xuICAgIDk5LCAxMjQsIDExOSwgMTIzLCAyNDIsIDEwNywgMTExLCAxOTcsIDQ4LCAxLCAxMDMsIDQzLCAyNTQsIDIxNSwgMTcxLFxuICAgIDExOCwgMjAyLCAxMzAsIDIwMSwgMTI1LCAyNTAsIDg5LCA3MSwgMjQwLCAxNzMsIDIxMiwgMTYyLCAxNzUsIDE1NiwgMTY0LFxuICAgIDExNCwgMTkyLCAxODMsIDI1MywgMTQ3LCAzOCwgNTQsIDYzLCAyNDcsIDIwNCwgNTIsIDE2NSwgMjI5LCAyNDEsIDExMyxcbiAgICAyMTYsIDQ5LCAyMSwgNCwgMTk5LCAzNSwgMTk1LCAyNCwgMTUwLCA1LCAxNTQsIDcsIDE4LCAxMjgsIDIyNixcbiAgICAyMzUsIDM5LCAxNzgsIDExNywgOSwgMTMxLCA0NCwgMjYsIDI3LCAxMTAsIDkwLCAxNjAsIDgyLCA1OSwgMjE0LFxuICAgIDE3OSwgNDEsIDIyNywgNDcsIDEzMiwgODMsIDIwOSwgMCwgMjM3LCAzMiwgMjUyLCAxNzcsIDkxLCAxMDYsIDIwMyxcbiAgICAxOTAsIDU3LCA3NCwgNzYsIDg4LCAyMDcsIDIwOCwgMjM5LCAxNzAsIDI1MSwgNjcsIDc3LCA1MSwgMTMzLCA2OSxcbiAgICAyNDksIDIsIDEyNywgODAsIDYwLCAxNTksIDE2OCwgODEsIDE2MywgNjQsIDE0MywgMTQ2LCAxNTcsIDU2LCAyNDUsXG4gICAgMTg4LCAxODIsIDIxOCwgMzMsIDE2LCAyNTUsIDI0MywgMjEwLCAyMDUsIDEyLCAxOSwgMjM2LCA5NSwgMTUxLCA2OCxcbiAgICAyMywgMTk2LCAxNjcsIDEyNiwgNjEsIDEwMCwgOTMsIDI1LCAxMTUsIDk2LCAxMjksIDc5LCAyMjAsIDM0LCA0MixcbiAgICAxNDQsIDEzNiwgNzAsIDIzOCwgMTg0LCAyMCwgMjIyLCA5NCwgMTEsIDIxOSwgMjI0LCA1MCwgNTgsIDEwLCA3MyxcbiAgICA2LCAzNiwgOTIsIDE5NCwgMjExLCAxNzIsIDk4LCAxNDUsIDE0OSwgMjI4LCAxMjEsIDIzMSwgMjAwLCA1NSwgMTA5LFxuICAgIDE0MSwgMjEzLCA3OCwgMTY5LCAxMDgsIDg2LCAyNDQsIDIzNCwgMTAxLCAxMjIsIDE3NCwgOCwgMTg2LCAxMjAsIDM3LFxuICAgIDQ2LCAyOCwgMTY2LCAxODAsIDE5OCwgMjMyLCAyMjEsIDExNiwgMzEsIDc1LCAxODksIDEzOSwgMTM4LCAxMTIsIDYyLFxuICAgIDE4MSwgMTAyLCA3MiwgMywgMjQ2LCAxNCwgOTcsIDUzLCA4NywgMTg1LCAxMzQsIDE5MywgMjksIDE1OCwgMjI1LFxuICAgIDI0OCwgMTUyLCAxNywgMTA1LCAyMTcsIDE0MiwgMTQ4LCAxNTUsIDMwLCAxMzUsIDIzMywgMjA2LCA4NSwgNDAsIDIyMyxcbiAgICAxNDAsIDE2MSwgMTM3LCAxMywgMTkxLCAyMzAsIDY2LCAxMDQsIDY1LCAxNTMsIDQ1LCAxNSwgMTc2LCA4NCwgMTg3LFxuICAgIDIyXG5dO1xuXG52YXIgVDEgPSBbXG4gICAgMHhhNTYzNjNjNiwgMHg4NDdjN2NmOCwgMHg5OTc3NzdlZSwgMHg4ZDdiN2JmNixcbiAgICAweDBkZjJmMmZmLCAweGJkNmI2YmQ2LCAweGIxNmY2ZmRlLCAweDU0YzVjNTkxLFxuICAgIDB4NTAzMDMwNjAsIDB4MDMwMTAxMDIsIDB4YTk2NzY3Y2UsIDB4N2QyYjJiNTYsXG4gICAgMHgxOWZlZmVlNywgMHg2MmQ3ZDdiNSwgMHhlNmFiYWI0ZCwgMHg5YTc2NzZlYyxcbiAgICAweDQ1Y2FjYThmLCAweDlkODI4MjFmLCAweDQwYzljOTg5LCAweDg3N2Q3ZGZhLFxuICAgIDB4MTVmYWZhZWYsIDB4ZWI1OTU5YjIsIDB4Yzk0NzQ3OGUsIDB4MGJmMGYwZmIsXG4gICAgMHhlY2FkYWQ0MSwgMHg2N2Q0ZDRiMywgMHhmZGEyYTI1ZiwgMHhlYWFmYWY0NSxcbiAgICAweGJmOWM5YzIzLCAweGY3YTRhNDUzLCAweDk2NzI3MmU0LCAweDViYzBjMDliLFxuICAgIDB4YzJiN2I3NzUsIDB4MWNmZGZkZTEsIDB4YWU5MzkzM2QsIDB4NmEyNjI2NGMsXG4gICAgMHg1YTM2MzY2YywgMHg0MTNmM2Y3ZSwgMHgwMmY3ZjdmNSwgMHg0ZmNjY2M4MyxcbiAgICAweDVjMzQzNDY4LCAweGY0YTVhNTUxLCAweDM0ZTVlNWQxLCAweDA4ZjFmMWY5LFxuICAgIDB4OTM3MTcxZTIsIDB4NzNkOGQ4YWIsIDB4NTMzMTMxNjIsIDB4M2YxNTE1MmEsXG4gICAgMHgwYzA0MDQwOCwgMHg1MmM3Yzc5NSwgMHg2NTIzMjM0NiwgMHg1ZWMzYzM5ZCxcbiAgICAweDI4MTgxODMwLCAweGExOTY5NjM3LCAweDBmMDUwNTBhLCAweGI1OWE5YTJmLFxuICAgIDB4MDkwNzA3MGUsIDB4MzYxMjEyMjQsIDB4OWI4MDgwMWIsIDB4M2RlMmUyZGYsXG4gICAgMHgyNmViZWJjZCwgMHg2OTI3Mjc0ZSwgMHhjZGIyYjI3ZiwgMHg5Zjc1NzVlYSxcbiAgICAweDFiMDkwOTEyLCAweDllODM4MzFkLCAweDc0MmMyYzU4LCAweDJlMWExYTM0LFxuICAgIDB4MmQxYjFiMzYsIDB4YjI2ZTZlZGMsIDB4ZWU1YTVhYjQsIDB4ZmJhMGEwNWIsXG4gICAgMHhmNjUyNTJhNCwgMHg0ZDNiM2I3NiwgMHg2MWQ2ZDZiNywgMHhjZWIzYjM3ZCxcbiAgICAweDdiMjkyOTUyLCAweDNlZTNlM2RkLCAweDcxMmYyZjVlLCAweDk3ODQ4NDEzLFxuICAgIDB4ZjU1MzUzYTYsIDB4NjhkMWQxYjksIDB4MDAwMDAwMDAsIDB4MmNlZGVkYzEsXG4gICAgMHg2MDIwMjA0MCwgMHgxZmZjZmNlMywgMHhjOGIxYjE3OSwgMHhlZDViNWJiNixcbiAgICAweGJlNmE2YWQ0LCAweDQ2Y2JjYjhkLCAweGQ5YmViZTY3LCAweDRiMzkzOTcyLFxuICAgIDB4ZGU0YTRhOTQsIDB4ZDQ0YzRjOTgsIDB4ZTg1ODU4YjAsIDB4NGFjZmNmODUsXG4gICAgMHg2YmQwZDBiYiwgMHgyYWVmZWZjNSwgMHhlNWFhYWE0ZiwgMHgxNmZiZmJlZCxcbiAgICAweGM1NDM0Mzg2LCAweGQ3NGQ0ZDlhLCAweDU1MzMzMzY2LCAweDk0ODU4NTExLFxuICAgIDB4Y2Y0NTQ1OGEsIDB4MTBmOWY5ZTksIDB4MDYwMjAyMDQsIDB4ODE3ZjdmZmUsXG4gICAgMHhmMDUwNTBhMCwgMHg0NDNjM2M3OCwgMHhiYTlmOWYyNSwgMHhlM2E4YTg0YixcbiAgICAweGYzNTE1MWEyLCAweGZlYTNhMzVkLCAweGMwNDA0MDgwLCAweDhhOGY4ZjA1LFxuICAgIDB4YWQ5MjkyM2YsIDB4YmM5ZDlkMjEsIDB4NDgzODM4NzAsIDB4MDRmNWY1ZjEsXG4gICAgMHhkZmJjYmM2MywgMHhjMWI2YjY3NywgMHg3NWRhZGFhZiwgMHg2MzIxMjE0MixcbiAgICAweDMwMTAxMDIwLCAweDFhZmZmZmU1LCAweDBlZjNmM2ZkLCAweDZkZDJkMmJmLFxuICAgIDB4NGNjZGNkODEsIDB4MTQwYzBjMTgsIDB4MzUxMzEzMjYsIDB4MmZlY2VjYzMsXG4gICAgMHhlMTVmNWZiZSwgMHhhMjk3OTczNSwgMHhjYzQ0NDQ4OCwgMHgzOTE3MTcyZSxcbiAgICAweDU3YzRjNDkzLCAweGYyYTdhNzU1LCAweDgyN2U3ZWZjLCAweDQ3M2QzZDdhLFxuICAgIDB4YWM2NDY0YzgsIDB4ZTc1ZDVkYmEsIDB4MmIxOTE5MzIsIDB4OTU3MzczZTYsXG4gICAgMHhhMDYwNjBjMCwgMHg5ODgxODExOSwgMHhkMTRmNGY5ZSwgMHg3ZmRjZGNhMyxcbiAgICAweDY2MjIyMjQ0LCAweDdlMmEyYTU0LCAweGFiOTA5MDNiLCAweDgzODg4ODBiLFxuICAgIDB4Y2E0NjQ2OGMsIDB4MjllZWVlYzcsIDB4ZDNiOGI4NmIsIDB4M2MxNDE0MjgsXG4gICAgMHg3OWRlZGVhNywgMHhlMjVlNWViYywgMHgxZDBiMGIxNiwgMHg3NmRiZGJhZCxcbiAgICAweDNiZTBlMGRiLCAweDU2MzIzMjY0LCAweDRlM2EzYTc0LCAweDFlMGEwYTE0LFxuICAgIDB4ZGI0OTQ5OTIsIDB4MGEwNjA2MGMsIDB4NmMyNDI0NDgsIDB4ZTQ1YzVjYjgsXG4gICAgMHg1ZGMyYzI5ZiwgMHg2ZWQzZDNiZCwgMHhlZmFjYWM0MywgMHhhNjYyNjJjNCxcbiAgICAweGE4OTE5MTM5LCAweGE0OTU5NTMxLCAweDM3ZTRlNGQzLCAweDhiNzk3OWYyLFxuICAgIDB4MzJlN2U3ZDUsIDB4NDNjOGM4OGIsIDB4NTkzNzM3NmUsIDB4Yjc2ZDZkZGEsXG4gICAgMHg4YzhkOGQwMSwgMHg2NGQ1ZDViMSwgMHhkMjRlNGU5YywgMHhlMGE5YTk0OSxcbiAgICAweGI0NmM2Y2Q4LCAweGZhNTY1NmFjLCAweDA3ZjRmNGYzLCAweDI1ZWFlYWNmLFxuICAgIDB4YWY2NTY1Y2EsIDB4OGU3YTdhZjQsIDB4ZTlhZWFlNDcsIDB4MTgwODA4MTAsXG4gICAgMHhkNWJhYmE2ZiwgMHg4ODc4NzhmMCwgMHg2ZjI1MjU0YSwgMHg3MjJlMmU1YyxcbiAgICAweDI0MWMxYzM4LCAweGYxYTZhNjU3LCAweGM3YjRiNDczLCAweDUxYzZjNjk3LFxuICAgIDB4MjNlOGU4Y2IsIDB4N2NkZGRkYTEsIDB4OWM3NDc0ZTgsIDB4MjExZjFmM2UsXG4gICAgMHhkZDRiNGI5NiwgMHhkY2JkYmQ2MSwgMHg4NjhiOGIwZCwgMHg4NThhOGEwZixcbiAgICAweDkwNzA3MGUwLCAweDQyM2UzZTdjLCAweGM0YjViNTcxLCAweGFhNjY2NmNjLFxuICAgIDB4ZDg0ODQ4OTAsIDB4MDUwMzAzMDYsIDB4MDFmNmY2ZjcsIDB4MTIwZTBlMWMsXG4gICAgMHhhMzYxNjFjMiwgMHg1ZjM1MzU2YSwgMHhmOTU3NTdhZSwgMHhkMGI5Yjk2OSxcbiAgICAweDkxODY4NjE3LCAweDU4YzFjMTk5LCAweDI3MWQxZDNhLCAweGI5OWU5ZTI3LFxuICAgIDB4MzhlMWUxZDksIDB4MTNmOGY4ZWIsIDB4YjM5ODk4MmIsIDB4MzMxMTExMjIsXG4gICAgMHhiYjY5NjlkMiwgMHg3MGQ5ZDlhOSwgMHg4OThlOGUwNywgMHhhNzk0OTQzMyxcbiAgICAweGI2OWI5YjJkLCAweDIyMWUxZTNjLCAweDkyODc4NzE1LCAweDIwZTllOWM5LFxuICAgIDB4NDljZWNlODcsIDB4ZmY1NTU1YWEsIDB4NzgyODI4NTAsIDB4N2FkZmRmYTUsXG4gICAgMHg4ZjhjOGMwMywgMHhmOGExYTE1OSwgMHg4MDg5ODkwOSwgMHgxNzBkMGQxYSxcbiAgICAweGRhYmZiZjY1LCAweDMxZTZlNmQ3LCAweGM2NDI0Mjg0LCAweGI4Njg2OGQwLFxuICAgIDB4YzM0MTQxODIsIDB4YjA5OTk5MjksIDB4NzcyZDJkNWEsIDB4MTEwZjBmMWUsXG4gICAgMHhjYmIwYjA3YiwgMHhmYzU0NTRhOCwgMHhkNmJiYmI2ZCwgMHgzYTE2MTYyY1xuXTtcblxudmFyIFQyID0gW1xuICAgIDB4NjM2M2M2YTUsIDB4N2M3Y2Y4ODQsIDB4Nzc3N2VlOTksIDB4N2I3YmY2OGQsXG4gICAgMHhmMmYyZmYwZCwgMHg2YjZiZDZiZCwgMHg2ZjZmZGViMSwgMHhjNWM1OTE1NCxcbiAgICAweDMwMzA2MDUwLCAweDAxMDEwMjAzLCAweDY3NjdjZWE5LCAweDJiMmI1NjdkLFxuICAgIDB4ZmVmZWU3MTksIDB4ZDdkN2I1NjIsIDB4YWJhYjRkZTYsIDB4NzY3NmVjOWEsXG4gICAgMHhjYWNhOGY0NSwgMHg4MjgyMWY5ZCwgMHhjOWM5ODk0MCwgMHg3ZDdkZmE4NyxcbiAgICAweGZhZmFlZjE1LCAweDU5NTliMmViLCAweDQ3NDc4ZWM5LCAweGYwZjBmYjBiLFxuICAgIDB4YWRhZDQxZWMsIDB4ZDRkNGIzNjcsIDB4YTJhMjVmZmQsIDB4YWZhZjQ1ZWEsXG4gICAgMHg5YzljMjNiZiwgMHhhNGE0NTNmNywgMHg3MjcyZTQ5NiwgMHhjMGMwOWI1YixcbiAgICAweGI3Yjc3NWMyLCAweGZkZmRlMTFjLCAweDkzOTMzZGFlLCAweDI2MjY0YzZhLFxuICAgIDB4MzYzNjZjNWEsIDB4M2YzZjdlNDEsIDB4ZjdmN2Y1MDIsIDB4Y2NjYzgzNGYsXG4gICAgMHgzNDM0Njg1YywgMHhhNWE1NTFmNCwgMHhlNWU1ZDEzNCwgMHhmMWYxZjkwOCxcbiAgICAweDcxNzFlMjkzLCAweGQ4ZDhhYjczLCAweDMxMzE2MjUzLCAweDE1MTUyYTNmLFxuICAgIDB4MDQwNDA4MGMsIDB4YzdjNzk1NTIsIDB4MjMyMzQ2NjUsIDB4YzNjMzlkNWUsXG4gICAgMHgxODE4MzAyOCwgMHg5Njk2MzdhMSwgMHgwNTA1MGEwZiwgMHg5YTlhMmZiNSxcbiAgICAweDA3MDcwZTA5LCAweDEyMTIyNDM2LCAweDgwODAxYjliLCAweGUyZTJkZjNkLFxuICAgIDB4ZWJlYmNkMjYsIDB4MjcyNzRlNjksIDB4YjJiMjdmY2QsIDB4NzU3NWVhOWYsXG4gICAgMHgwOTA5MTIxYiwgMHg4MzgzMWQ5ZSwgMHgyYzJjNTg3NCwgMHgxYTFhMzQyZSxcbiAgICAweDFiMWIzNjJkLCAweDZlNmVkY2IyLCAweDVhNWFiNGVlLCAweGEwYTA1YmZiLFxuICAgIDB4NTI1MmE0ZjYsIDB4M2IzYjc2NGQsIDB4ZDZkNmI3NjEsIDB4YjNiMzdkY2UsXG4gICAgMHgyOTI5NTI3YiwgMHhlM2UzZGQzZSwgMHgyZjJmNWU3MSwgMHg4NDg0MTM5NyxcbiAgICAweDUzNTNhNmY1LCAweGQxZDFiOTY4LCAweDAwMDAwMDAwLCAweGVkZWRjMTJjLFxuICAgIDB4MjAyMDQwNjAsIDB4ZmNmY2UzMWYsIDB4YjFiMTc5YzgsIDB4NWI1YmI2ZWQsXG4gICAgMHg2YTZhZDRiZSwgMHhjYmNiOGQ0NiwgMHhiZWJlNjdkOSwgMHgzOTM5NzI0YixcbiAgICAweDRhNGE5NGRlLCAweDRjNGM5OGQ0LCAweDU4NThiMGU4LCAweGNmY2Y4NTRhLFxuICAgIDB4ZDBkMGJiNmIsIDB4ZWZlZmM1MmEsIDB4YWFhYTRmZTUsIDB4ZmJmYmVkMTYsXG4gICAgMHg0MzQzODZjNSwgMHg0ZDRkOWFkNywgMHgzMzMzNjY1NSwgMHg4NTg1MTE5NCxcbiAgICAweDQ1NDU4YWNmLCAweGY5ZjllOTEwLCAweDAyMDIwNDA2LCAweDdmN2ZmZTgxLFxuICAgIDB4NTA1MGEwZjAsIDB4M2MzYzc4NDQsIDB4OWY5ZjI1YmEsIDB4YThhODRiZTMsXG4gICAgMHg1MTUxYTJmMywgMHhhM2EzNWRmZSwgMHg0MDQwODBjMCwgMHg4ZjhmMDU4YSxcbiAgICAweDkyOTIzZmFkLCAweDlkOWQyMWJjLCAweDM4Mzg3MDQ4LCAweGY1ZjVmMTA0LFxuICAgIDB4YmNiYzYzZGYsIDB4YjZiNjc3YzEsIDB4ZGFkYWFmNzUsIDB4MjEyMTQyNjMsXG4gICAgMHgxMDEwMjAzMCwgMHhmZmZmZTUxYSwgMHhmM2YzZmQwZSwgMHhkMmQyYmY2ZCxcbiAgICAweGNkY2Q4MTRjLCAweDBjMGMxODE0LCAweDEzMTMyNjM1LCAweGVjZWNjMzJmLFxuICAgIDB4NWY1ZmJlZTEsIDB4OTc5NzM1YTIsIDB4NDQ0NDg4Y2MsIDB4MTcxNzJlMzksXG4gICAgMHhjNGM0OTM1NywgMHhhN2E3NTVmMiwgMHg3ZTdlZmM4MiwgMHgzZDNkN2E0NyxcbiAgICAweDY0NjRjOGFjLCAweDVkNWRiYWU3LCAweDE5MTkzMjJiLCAweDczNzNlNjk1LFxuICAgIDB4NjA2MGMwYTAsIDB4ODE4MTE5OTgsIDB4NGY0ZjllZDEsIDB4ZGNkY2EzN2YsXG4gICAgMHgyMjIyNDQ2NiwgMHgyYTJhNTQ3ZSwgMHg5MDkwM2JhYiwgMHg4ODg4MGI4MyxcbiAgICAweDQ2NDY4Y2NhLCAweGVlZWVjNzI5LCAweGI4Yjg2YmQzLCAweDE0MTQyODNjLFxuICAgIDB4ZGVkZWE3NzksIDB4NWU1ZWJjZTIsIDB4MGIwYjE2MWQsIDB4ZGJkYmFkNzYsXG4gICAgMHhlMGUwZGIzYiwgMHgzMjMyNjQ1NiwgMHgzYTNhNzQ0ZSwgMHgwYTBhMTQxZSxcbiAgICAweDQ5NDk5MmRiLCAweDA2MDYwYzBhLCAweDI0MjQ0ODZjLCAweDVjNWNiOGU0LFxuICAgIDB4YzJjMjlmNWQsIDB4ZDNkM2JkNmUsIDB4YWNhYzQzZWYsIDB4NjI2MmM0YTYsXG4gICAgMHg5MTkxMzlhOCwgMHg5NTk1MzFhNCwgMHhlNGU0ZDMzNywgMHg3OTc5ZjI4YixcbiAgICAweGU3ZTdkNTMyLCAweGM4Yzg4YjQzLCAweDM3Mzc2ZTU5LCAweDZkNmRkYWI3LFxuICAgIDB4OGQ4ZDAxOGMsIDB4ZDVkNWIxNjQsIDB4NGU0ZTljZDIsIDB4YTlhOTQ5ZTAsXG4gICAgMHg2YzZjZDhiNCwgMHg1NjU2YWNmYSwgMHhmNGY0ZjMwNywgMHhlYWVhY2YyNSxcbiAgICAweDY1NjVjYWFmLCAweDdhN2FmNDhlLCAweGFlYWU0N2U5LCAweDA4MDgxMDE4LFxuICAgIDB4YmFiYTZmZDUsIDB4Nzg3OGYwODgsIDB4MjUyNTRhNmYsIDB4MmUyZTVjNzIsXG4gICAgMHgxYzFjMzgyNCwgMHhhNmE2NTdmMSwgMHhiNGI0NzNjNywgMHhjNmM2OTc1MSxcbiAgICAweGU4ZThjYjIzLCAweGRkZGRhMTdjLCAweDc0NzRlODljLCAweDFmMWYzZTIxLFxuICAgIDB4NGI0Yjk2ZGQsIDB4YmRiZDYxZGMsIDB4OGI4YjBkODYsIDB4OGE4YTBmODUsXG4gICAgMHg3MDcwZTA5MCwgMHgzZTNlN2M0MiwgMHhiNWI1NzFjNCwgMHg2NjY2Y2NhYSxcbiAgICAweDQ4NDg5MGQ4LCAweDAzMDMwNjA1LCAweGY2ZjZmNzAxLCAweDBlMGUxYzEyLFxuICAgIDB4NjE2MWMyYTMsIDB4MzUzNTZhNWYsIDB4NTc1N2FlZjksIDB4YjliOTY5ZDAsXG4gICAgMHg4Njg2MTc5MSwgMHhjMWMxOTk1OCwgMHgxZDFkM2EyNywgMHg5ZTllMjdiOSxcbiAgICAweGUxZTFkOTM4LCAweGY4ZjhlYjEzLCAweDk4OTgyYmIzLCAweDExMTEyMjMzLFxuICAgIDB4Njk2OWQyYmIsIDB4ZDlkOWE5NzAsIDB4OGU4ZTA3ODksIDB4OTQ5NDMzYTcsXG4gICAgMHg5YjliMmRiNiwgMHgxZTFlM2MyMiwgMHg4Nzg3MTU5MiwgMHhlOWU5YzkyMCxcbiAgICAweGNlY2U4NzQ5LCAweDU1NTVhYWZmLCAweDI4Mjg1MDc4LCAweGRmZGZhNTdhLFxuICAgIDB4OGM4YzAzOGYsIDB4YTFhMTU5ZjgsIDB4ODk4OTA5ODAsIDB4MGQwZDFhMTcsXG4gICAgMHhiZmJmNjVkYSwgMHhlNmU2ZDczMSwgMHg0MjQyODRjNiwgMHg2ODY4ZDBiOCxcbiAgICAweDQxNDE4MmMzLCAweDk5OTkyOWIwLCAweDJkMmQ1YTc3LCAweDBmMGYxZTExLFxuICAgIDB4YjBiMDdiY2IsIDB4NTQ1NGE4ZmMsIDB4YmJiYjZkZDYsIDB4MTYxNjJjM2Fcbl07XG5cbnZhciBUMyA9IFtcbiAgICAweDYzYzZhNTYzLCAweDdjZjg4NDdjLCAweDc3ZWU5OTc3LCAweDdiZjY4ZDdiLFxuICAgIDB4ZjJmZjBkZjIsIDB4NmJkNmJkNmIsIDB4NmZkZWIxNmYsIDB4YzU5MTU0YzUsXG4gICAgMHgzMDYwNTAzMCwgMHgwMTAyMDMwMSwgMHg2N2NlYTk2NywgMHgyYjU2N2QyYixcbiAgICAweGZlZTcxOWZlLCAweGQ3YjU2MmQ3LCAweGFiNGRlNmFiLCAweDc2ZWM5YTc2LFxuICAgIDB4Y2E4ZjQ1Y2EsIDB4ODIxZjlkODIsIDB4Yzk4OTQwYzksIDB4N2RmYTg3N2QsXG4gICAgMHhmYWVmMTVmYSwgMHg1OWIyZWI1OSwgMHg0NzhlYzk0NywgMHhmMGZiMGJmMCxcbiAgICAweGFkNDFlY2FkLCAweGQ0YjM2N2Q0LCAweGEyNWZmZGEyLCAweGFmNDVlYWFmLFxuICAgIDB4OWMyM2JmOWMsIDB4YTQ1M2Y3YTQsIDB4NzJlNDk2NzIsIDB4YzA5YjViYzAsXG4gICAgMHhiNzc1YzJiNywgMHhmZGUxMWNmZCwgMHg5MzNkYWU5MywgMHgyNjRjNmEyNixcbiAgICAweDM2NmM1YTM2LCAweDNmN2U0MTNmLCAweGY3ZjUwMmY3LCAweGNjODM0ZmNjLFxuICAgIDB4MzQ2ODVjMzQsIDB4YTU1MWY0YTUsIDB4ZTVkMTM0ZTUsIDB4ZjFmOTA4ZjEsXG4gICAgMHg3MWUyOTM3MSwgMHhkOGFiNzNkOCwgMHgzMTYyNTMzMSwgMHgxNTJhM2YxNSxcbiAgICAweDA0MDgwYzA0LCAweGM3OTU1MmM3LCAweDIzNDY2NTIzLCAweGMzOWQ1ZWMzLFxuICAgIDB4MTgzMDI4MTgsIDB4OTYzN2ExOTYsIDB4MDUwYTBmMDUsIDB4OWEyZmI1OWEsXG4gICAgMHgwNzBlMDkwNywgMHgxMjI0MzYxMiwgMHg4MDFiOWI4MCwgMHhlMmRmM2RlMixcbiAgICAweGViY2QyNmViLCAweDI3NGU2OTI3LCAweGIyN2ZjZGIyLCAweDc1ZWE5Zjc1LFxuICAgIDB4MDkxMjFiMDksIDB4ODMxZDllODMsIDB4MmM1ODc0MmMsIDB4MWEzNDJlMWEsXG4gICAgMHgxYjM2MmQxYiwgMHg2ZWRjYjI2ZSwgMHg1YWI0ZWU1YSwgMHhhMDViZmJhMCxcbiAgICAweDUyYTRmNjUyLCAweDNiNzY0ZDNiLCAweGQ2Yjc2MWQ2LCAweGIzN2RjZWIzLFxuICAgIDB4Mjk1MjdiMjksIDB4ZTNkZDNlZTMsIDB4MmY1ZTcxMmYsIDB4ODQxMzk3ODQsXG4gICAgMHg1M2E2ZjU1MywgMHhkMWI5NjhkMSwgMHgwMDAwMDAwMCwgMHhlZGMxMmNlZCxcbiAgICAweDIwNDA2MDIwLCAweGZjZTMxZmZjLCAweGIxNzljOGIxLCAweDViYjZlZDViLFxuICAgIDB4NmFkNGJlNmEsIDB4Y2I4ZDQ2Y2IsIDB4YmU2N2Q5YmUsIDB4Mzk3MjRiMzksXG4gICAgMHg0YTk0ZGU0YSwgMHg0Yzk4ZDQ0YywgMHg1OGIwZTg1OCwgMHhjZjg1NGFjZixcbiAgICAweGQwYmI2YmQwLCAweGVmYzUyYWVmLCAweGFhNGZlNWFhLCAweGZiZWQxNmZiLFxuICAgIDB4NDM4NmM1NDMsIDB4NGQ5YWQ3NGQsIDB4MzM2NjU1MzMsIDB4ODUxMTk0ODUsXG4gICAgMHg0NThhY2Y0NSwgMHhmOWU5MTBmOSwgMHgwMjA0MDYwMiwgMHg3ZmZlODE3ZixcbiAgICAweDUwYTBmMDUwLCAweDNjNzg0NDNjLCAweDlmMjViYTlmLCAweGE4NGJlM2E4LFxuICAgIDB4NTFhMmYzNTEsIDB4YTM1ZGZlYTMsIDB4NDA4MGMwNDAsIDB4OGYwNThhOGYsXG4gICAgMHg5MjNmYWQ5MiwgMHg5ZDIxYmM5ZCwgMHgzODcwNDgzOCwgMHhmNWYxMDRmNSxcbiAgICAweGJjNjNkZmJjLCAweGI2NzdjMWI2LCAweGRhYWY3NWRhLCAweDIxNDI2MzIxLFxuICAgIDB4MTAyMDMwMTAsIDB4ZmZlNTFhZmYsIDB4ZjNmZDBlZjMsIDB4ZDJiZjZkZDIsXG4gICAgMHhjZDgxNGNjZCwgMHgwYzE4MTQwYywgMHgxMzI2MzUxMywgMHhlY2MzMmZlYyxcbiAgICAweDVmYmVlMTVmLCAweDk3MzVhMjk3LCAweDQ0ODhjYzQ0LCAweDE3MmUzOTE3LFxuICAgIDB4YzQ5MzU3YzQsIDB4YTc1NWYyYTcsIDB4N2VmYzgyN2UsIDB4M2Q3YTQ3M2QsXG4gICAgMHg2NGM4YWM2NCwgMHg1ZGJhZTc1ZCwgMHgxOTMyMmIxOSwgMHg3M2U2OTU3MyxcbiAgICAweDYwYzBhMDYwLCAweDgxMTk5ODgxLCAweDRmOWVkMTRmLCAweGRjYTM3ZmRjLFxuICAgIDB4MjI0NDY2MjIsIDB4MmE1NDdlMmEsIDB4OTAzYmFiOTAsIDB4ODgwYjgzODgsXG4gICAgMHg0NjhjY2E0NiwgMHhlZWM3MjllZSwgMHhiODZiZDNiOCwgMHgxNDI4M2MxNCxcbiAgICAweGRlYTc3OWRlLCAweDVlYmNlMjVlLCAweDBiMTYxZDBiLCAweGRiYWQ3NmRiLFxuICAgIDB4ZTBkYjNiZTAsIDB4MzI2NDU2MzIsIDB4M2E3NDRlM2EsIDB4MGExNDFlMGEsXG4gICAgMHg0OTkyZGI0OSwgMHgwNjBjMGEwNiwgMHgyNDQ4NmMyNCwgMHg1Y2I4ZTQ1YyxcbiAgICAweGMyOWY1ZGMyLCAweGQzYmQ2ZWQzLCAweGFjNDNlZmFjLCAweDYyYzRhNjYyLFxuICAgIDB4OTEzOWE4OTEsIDB4OTUzMWE0OTUsIDB4ZTRkMzM3ZTQsIDB4NzlmMjhiNzksXG4gICAgMHhlN2Q1MzJlNywgMHhjODhiNDNjOCwgMHgzNzZlNTkzNywgMHg2ZGRhYjc2ZCxcbiAgICAweDhkMDE4YzhkLCAweGQ1YjE2NGQ1LCAweDRlOWNkMjRlLCAweGE5NDllMGE5LFxuICAgIDB4NmNkOGI0NmMsIDB4NTZhY2ZhNTYsIDB4ZjRmMzA3ZjQsIDB4ZWFjZjI1ZWEsXG4gICAgMHg2NWNhYWY2NSwgMHg3YWY0OGU3YSwgMHhhZTQ3ZTlhZSwgMHgwODEwMTgwOCxcbiAgICAweGJhNmZkNWJhLCAweDc4ZjA4ODc4LCAweDI1NGE2ZjI1LCAweDJlNWM3MjJlLFxuICAgIDB4MWMzODI0MWMsIDB4YTY1N2YxYTYsIDB4YjQ3M2M3YjQsIDB4YzY5NzUxYzYsXG4gICAgMHhlOGNiMjNlOCwgMHhkZGExN2NkZCwgMHg3NGU4OWM3NCwgMHgxZjNlMjExZixcbiAgICAweDRiOTZkZDRiLCAweGJkNjFkY2JkLCAweDhiMGQ4NjhiLCAweDhhMGY4NThhLFxuICAgIDB4NzBlMDkwNzAsIDB4M2U3YzQyM2UsIDB4YjU3MWM0YjUsIDB4NjZjY2FhNjYsXG4gICAgMHg0ODkwZDg0OCwgMHgwMzA2MDUwMywgMHhmNmY3MDFmNiwgMHgwZTFjMTIwZSxcbiAgICAweDYxYzJhMzYxLCAweDM1NmE1ZjM1LCAweDU3YWVmOTU3LCAweGI5NjlkMGI5LFxuICAgIDB4ODYxNzkxODYsIDB4YzE5OTU4YzEsIDB4MWQzYTI3MWQsIDB4OWUyN2I5OWUsXG4gICAgMHhlMWQ5MzhlMSwgMHhmOGViMTNmOCwgMHg5ODJiYjM5OCwgMHgxMTIyMzMxMSxcbiAgICAweDY5ZDJiYjY5LCAweGQ5YTk3MGQ5LCAweDhlMDc4OThlLCAweDk0MzNhNzk0LFxuICAgIDB4OWIyZGI2OWIsIDB4MWUzYzIyMWUsIDB4ODcxNTkyODcsIDB4ZTljOTIwZTksXG4gICAgMHhjZTg3NDljZSwgMHg1NWFhZmY1NSwgMHgyODUwNzgyOCwgMHhkZmE1N2FkZixcbiAgICAweDhjMDM4ZjhjLCAweGExNTlmOGExLCAweDg5MDk4MDg5LCAweDBkMWExNzBkLFxuICAgIDB4YmY2NWRhYmYsIDB4ZTZkNzMxZTYsIDB4NDI4NGM2NDIsIDB4NjhkMGI4NjgsXG4gICAgMHg0MTgyYzM0MSwgMHg5OTI5YjA5OSwgMHgyZDVhNzcyZCwgMHgwZjFlMTEwZixcbiAgICAweGIwN2JjYmIwLCAweDU0YThmYzU0LCAweGJiNmRkNmJiLCAweDE2MmMzYTE2XG5dO1xuXG52YXIgVDQgPSBbXG4gICAgMHhjNmE1NjM2MywgMHhmODg0N2M3YywgMHhlZTk5Nzc3NywgMHhmNjhkN2I3YixcbiAgICAweGZmMGRmMmYyLCAweGQ2YmQ2YjZiLCAweGRlYjE2ZjZmLCAweDkxNTRjNWM1LFxuICAgIDB4NjA1MDMwMzAsIDB4MDIwMzAxMDEsIDB4Y2VhOTY3NjcsIDB4NTY3ZDJiMmIsXG4gICAgMHhlNzE5ZmVmZSwgMHhiNTYyZDdkNywgMHg0ZGU2YWJhYiwgMHhlYzlhNzY3NixcbiAgICAweDhmNDVjYWNhLCAweDFmOWQ4MjgyLCAweDg5NDBjOWM5LCAweGZhODc3ZDdkLFxuICAgIDB4ZWYxNWZhZmEsIDB4YjJlYjU5NTksIDB4OGVjOTQ3NDcsIDB4ZmIwYmYwZjAsXG4gICAgMHg0MWVjYWRhZCwgMHhiMzY3ZDRkNCwgMHg1ZmZkYTJhMiwgMHg0NWVhYWZhZixcbiAgICAweDIzYmY5YzljLCAweDUzZjdhNGE0LCAweGU0OTY3MjcyLCAweDliNWJjMGMwLFxuICAgIDB4NzVjMmI3YjcsIDB4ZTExY2ZkZmQsIDB4M2RhZTkzOTMsIDB4NGM2YTI2MjYsXG4gICAgMHg2YzVhMzYzNiwgMHg3ZTQxM2YzZiwgMHhmNTAyZjdmNywgMHg4MzRmY2NjYyxcbiAgICAweDY4NWMzNDM0LCAweDUxZjRhNWE1LCAweGQxMzRlNWU1LCAweGY5MDhmMWYxLFxuICAgIDB4ZTI5MzcxNzEsIDB4YWI3M2Q4ZDgsIDB4NjI1MzMxMzEsIDB4MmEzZjE1MTUsXG4gICAgMHgwODBjMDQwNCwgMHg5NTUyYzdjNywgMHg0NjY1MjMyMywgMHg5ZDVlYzNjMyxcbiAgICAweDMwMjgxODE4LCAweDM3YTE5Njk2LCAweDBhMGYwNTA1LCAweDJmYjU5YTlhLFxuICAgIDB4MGUwOTA3MDcsIDB4MjQzNjEyMTIsIDB4MWI5YjgwODAsIDB4ZGYzZGUyZTIsXG4gICAgMHhjZDI2ZWJlYiwgMHg0ZTY5MjcyNywgMHg3ZmNkYjJiMiwgMHhlYTlmNzU3NSxcbiAgICAweDEyMWIwOTA5LCAweDFkOWU4MzgzLCAweDU4NzQyYzJjLCAweDM0MmUxYTFhLFxuICAgIDB4MzYyZDFiMWIsIDB4ZGNiMjZlNmUsIDB4YjRlZTVhNWEsIDB4NWJmYmEwYTAsXG4gICAgMHhhNGY2NTI1MiwgMHg3NjRkM2IzYiwgMHhiNzYxZDZkNiwgMHg3ZGNlYjNiMyxcbiAgICAweDUyN2IyOTI5LCAweGRkM2VlM2UzLCAweDVlNzEyZjJmLCAweDEzOTc4NDg0LFxuICAgIDB4YTZmNTUzNTMsIDB4Yjk2OGQxZDEsIDB4MDAwMDAwMDAsIDB4YzEyY2VkZWQsXG4gICAgMHg0MDYwMjAyMCwgMHhlMzFmZmNmYywgMHg3OWM4YjFiMSwgMHhiNmVkNWI1YixcbiAgICAweGQ0YmU2YTZhLCAweDhkNDZjYmNiLCAweDY3ZDliZWJlLCAweDcyNGIzOTM5LFxuICAgIDB4OTRkZTRhNGEsIDB4OThkNDRjNGMsIDB4YjBlODU4NTgsIDB4ODU0YWNmY2YsXG4gICAgMHhiYjZiZDBkMCwgMHhjNTJhZWZlZiwgMHg0ZmU1YWFhYSwgMHhlZDE2ZmJmYixcbiAgICAweDg2YzU0MzQzLCAweDlhZDc0ZDRkLCAweDY2NTUzMzMzLCAweDExOTQ4NTg1LFxuICAgIDB4OGFjZjQ1NDUsIDB4ZTkxMGY5ZjksIDB4MDQwNjAyMDIsIDB4ZmU4MTdmN2YsXG4gICAgMHhhMGYwNTA1MCwgMHg3ODQ0M2MzYywgMHgyNWJhOWY5ZiwgMHg0YmUzYThhOCxcbiAgICAweGEyZjM1MTUxLCAweDVkZmVhM2EzLCAweDgwYzA0MDQwLCAweDA1OGE4ZjhmLFxuICAgIDB4M2ZhZDkyOTIsIDB4MjFiYzlkOWQsIDB4NzA0ODM4MzgsIDB4ZjEwNGY1ZjUsXG4gICAgMHg2M2RmYmNiYywgMHg3N2MxYjZiNiwgMHhhZjc1ZGFkYSwgMHg0MjYzMjEyMSxcbiAgICAweDIwMzAxMDEwLCAweGU1MWFmZmZmLCAweGZkMGVmM2YzLCAweGJmNmRkMmQyLFxuICAgIDB4ODE0Y2NkY2QsIDB4MTgxNDBjMGMsIDB4MjYzNTEzMTMsIDB4YzMyZmVjZWMsXG4gICAgMHhiZWUxNWY1ZiwgMHgzNWEyOTc5NywgMHg4OGNjNDQ0NCwgMHgyZTM5MTcxNyxcbiAgICAweDkzNTdjNGM0LCAweDU1ZjJhN2E3LCAweGZjODI3ZTdlLCAweDdhNDczZDNkLFxuICAgIDB4YzhhYzY0NjQsIDB4YmFlNzVkNWQsIDB4MzIyYjE5MTksIDB4ZTY5NTczNzMsXG4gICAgMHhjMGEwNjA2MCwgMHgxOTk4ODE4MSwgMHg5ZWQxNGY0ZiwgMHhhMzdmZGNkYyxcbiAgICAweDQ0NjYyMjIyLCAweDU0N2UyYTJhLCAweDNiYWI5MDkwLCAweDBiODM4ODg4LFxuICAgIDB4OGNjYTQ2NDYsIDB4YzcyOWVlZWUsIDB4NmJkM2I4YjgsIDB4MjgzYzE0MTQsXG4gICAgMHhhNzc5ZGVkZSwgMHhiY2UyNWU1ZSwgMHgxNjFkMGIwYiwgMHhhZDc2ZGJkYixcbiAgICAweGRiM2JlMGUwLCAweDY0NTYzMjMyLCAweDc0NGUzYTNhLCAweDE0MWUwYTBhLFxuICAgIDB4OTJkYjQ5NDksIDB4MGMwYTA2MDYsIDB4NDg2YzI0MjQsIDB4YjhlNDVjNWMsXG4gICAgMHg5ZjVkYzJjMiwgMHhiZDZlZDNkMywgMHg0M2VmYWNhYywgMHhjNGE2NjI2MixcbiAgICAweDM5YTg5MTkxLCAweDMxYTQ5NTk1LCAweGQzMzdlNGU0LCAweGYyOGI3OTc5LFxuICAgIDB4ZDUzMmU3ZTcsIDB4OGI0M2M4YzgsIDB4NmU1OTM3MzcsIDB4ZGFiNzZkNmQsXG4gICAgMHgwMThjOGQ4ZCwgMHhiMTY0ZDVkNSwgMHg5Y2QyNGU0ZSwgMHg0OWUwYTlhOSxcbiAgICAweGQ4YjQ2YzZjLCAweGFjZmE1NjU2LCAweGYzMDdmNGY0LCAweGNmMjVlYWVhLFxuICAgIDB4Y2FhZjY1NjUsIDB4ZjQ4ZTdhN2EsIDB4NDdlOWFlYWUsIDB4MTAxODA4MDgsXG4gICAgMHg2ZmQ1YmFiYSwgMHhmMDg4Nzg3OCwgMHg0YTZmMjUyNSwgMHg1YzcyMmUyZSxcbiAgICAweDM4MjQxYzFjLCAweDU3ZjFhNmE2LCAweDczYzdiNGI0LCAweDk3NTFjNmM2LFxuICAgIDB4Y2IyM2U4ZTgsIDB4YTE3Y2RkZGQsIDB4ZTg5Yzc0NzQsIDB4M2UyMTFmMWYsXG4gICAgMHg5NmRkNGI0YiwgMHg2MWRjYmRiZCwgMHgwZDg2OGI4YiwgMHgwZjg1OGE4YSxcbiAgICAweGUwOTA3MDcwLCAweDdjNDIzZTNlLCAweDcxYzRiNWI1LCAweGNjYWE2NjY2LFxuICAgIDB4OTBkODQ4NDgsIDB4MDYwNTAzMDMsIDB4ZjcwMWY2ZjYsIDB4MWMxMjBlMGUsXG4gICAgMHhjMmEzNjE2MSwgMHg2YTVmMzUzNSwgMHhhZWY5NTc1NywgMHg2OWQwYjliOSxcbiAgICAweDE3OTE4Njg2LCAweDk5NThjMWMxLCAweDNhMjcxZDFkLCAweDI3Yjk5ZTllLFxuICAgIDB4ZDkzOGUxZTEsIDB4ZWIxM2Y4ZjgsIDB4MmJiMzk4OTgsIDB4MjIzMzExMTEsXG4gICAgMHhkMmJiNjk2OSwgMHhhOTcwZDlkOSwgMHgwNzg5OGU4ZSwgMHgzM2E3OTQ5NCxcbiAgICAweDJkYjY5YjliLCAweDNjMjIxZTFlLCAweDE1OTI4Nzg3LCAweGM5MjBlOWU5LFxuICAgIDB4ODc0OWNlY2UsIDB4YWFmZjU1NTUsIDB4NTA3ODI4MjgsIDB4YTU3YWRmZGYsXG4gICAgMHgwMzhmOGM4YywgMHg1OWY4YTFhMSwgMHgwOTgwODk4OSwgMHgxYTE3MGQwZCxcbiAgICAweDY1ZGFiZmJmLCAweGQ3MzFlNmU2LCAweDg0YzY0MjQyLCAweGQwYjg2ODY4LFxuICAgIDB4ODJjMzQxNDEsIDB4MjliMDk5OTksIDB4NWE3NzJkMmQsIDB4MWUxMTBmMGYsXG4gICAgMHg3YmNiYjBiMCwgMHhhOGZjNTQ1NCwgMHg2ZGQ2YmJiYiwgMHgyYzNhMTYxNlxuXTtcblxuZnVuY3Rpb24gQjAoeCkge1xuICByZXR1cm4gKHggJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMSh4KSB7XG4gIHJldHVybiAoKHggPj4gOCkgJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMih4KSB7XG4gIHJldHVybiAoKHggPj4gMTYpICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gQjMoeCkge1xuICByZXR1cm4gKCh4ID4+IDI0KSAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEYxKHgwLCB4MSwgeDIsIHgzKSB7XG4gIHJldHVybiBCMShUMVt4MCAmIDI1NV0pIHwgKEIxKFQxWyh4MSA+PiA4KSAmIDI1NV0pIDw8IDgpIHwgKEIxKFQxWyh4MiA+PiAxNikgJiAyNTVdKSA8PCAxNikgfCAoQjEoVDFbeDMgPj4+IDI0XSkgPDxcbiAgICAyNCk7XG59XG5cbmZ1bmN0aW9uIHBhY2tCeXRlcyhvY3RldHMpIHtcbiAgdmFyIGksIGo7XG4gIHZhciBsZW4gPSBvY3RldHMubGVuZ3RoO1xuICB2YXIgYiA9IG5ldyBBcnJheShsZW4gLyA0KTtcblxuICBpZiAoIW9jdGV0cyB8fCBsZW4gJSA0KSByZXR1cm47XG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGogPCBsZW47IGogKz0gNClcbiAgICBiW2krK10gPSBvY3RldHNbal0gfCAob2N0ZXRzW2ogKyAxXSA8PCA4KSB8IChvY3RldHNbaiArIDJdIDw8IDE2KSB8IChvY3RldHNbaiArIDNdIDw8IDI0KTtcblxuICByZXR1cm4gYjtcbn1cblxuZnVuY3Rpb24gdW5wYWNrQnl0ZXMocGFja2VkKSB7XG4gIHZhciBqO1xuICB2YXIgaSA9IDAsXG4gICAgbCA9IHBhY2tlZC5sZW5ndGg7XG4gIHZhciByID0gbmV3IEFycmF5KGwgKiA0KTtcblxuICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgcltpKytdID0gQjAocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMShwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIyKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjMocGFja2VkW2pdKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnZhciBtYXhrYyA9IDg7XG52YXIgbWF4cmsgPSAxNDtcblxuZnVuY3Rpb24ga2V5RXhwYW5zaW9uKGtleSkge1xuICB2YXIga2MsIGksIGosIHIsIHQ7XG4gIHZhciByb3VuZHM7XG4gIHZhciBrZXlTY2hlZCA9IG5ldyBBcnJheShtYXhyayArIDEpO1xuICB2YXIga2V5bGVuID0ga2V5Lmxlbmd0aDtcbiAgdmFyIGsgPSBuZXcgQXJyYXkobWF4a2MpO1xuICB2YXIgdGsgPSBuZXcgQXJyYXkobWF4a2MpO1xuICB2YXIgcmNvbnBvaW50ZXIgPSAwO1xuXG4gIGlmIChrZXlsZW4gPT0gMTYpIHtcbiAgICByb3VuZHMgPSAxMDtcbiAgICBrYyA9IDQ7XG4gIH0gZWxzZSBpZiAoa2V5bGVuID09IDI0KSB7XG4gICAgcm91bmRzID0gMTI7XG4gICAga2MgPSA2O1xuICB9IGVsc2UgaWYgKGtleWxlbiA9PSAzMikge1xuICAgIHJvdW5kcyA9IDE0O1xuICAgIGtjID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5LWxlbmd0aCBmb3IgQUVTIGtleTonICsga2V5bGVuKTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCBtYXhyayArIDE7IGkrKykga2V5U2NoZWRbaV0gPSBuZXcgQXJyYXkoNCk7XG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGogPCBrZXlsZW47IGorKywgaSArPSA0KVxuICAgIGtbal0gPSBrZXkuY2hhckNvZGVBdChpKSB8IChrZXkuY2hhckNvZGVBdChpICsgMSkgPDwgOCkgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDIpIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcblxuICBmb3IgKGogPSBrYyAtIDE7IGogPj0gMDsgai0tKSB0a1tqXSA9IGtbal07XG5cbiAgciA9IDA7XG4gIHQgPSAwO1xuICBmb3IgKGogPSAwO1xuICAoaiA8IGtjKSAmJiAociA8IHJvdW5kcyArIDEpOykge1xuICAgIGZvciAoO1xuICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICBrZXlTY2hlZFtyXVt0XSA9IHRrW2pdO1xuICAgIH1cbiAgICBpZiAodCA9PSA0KSB7XG4gICAgICByKys7XG4gICAgICB0ID0gMDtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAociA8IHJvdW5kcyArIDEpIHtcbiAgICB2YXIgdGVtcCA9IHRrW2tjIC0gMV07XG5cbiAgICB0a1swXSBePSBTW0IxKHRlbXApXSB8IChTW0IyKHRlbXApXSA8PCA4KSB8IChTW0IzKHRlbXApXSA8PCAxNikgfCAoU1tCMCh0ZW1wKV0gPDwgMjQpO1xuICAgIHRrWzBdIF49IFJjb25bcmNvbnBvaW50ZXIrK107XG5cbiAgICBpZiAoa2MgIT0gOCkge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjIC8gMjsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG5cbiAgICAgIHRlbXAgPSB0a1trYyAvIDIgLSAxXTtcbiAgICAgIHRrW2tjIC8gMl0gXj0gU1tCMCh0ZW1wKV0gfCAoU1tCMSh0ZW1wKV0gPDwgOCkgfCAoU1tCMih0ZW1wKV0gPDwgMTYpIHwgKFNbQjModGVtcCldIDw8IDI0KTtcblxuICAgICAgZm9yIChqID0ga2MgLyAyICsgMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9XG5cbiAgICBmb3IgKGogPSAwO1xuICAgIChqIDwga2MpICYmIChyIDwgcm91bmRzICsgMSk7KSB7XG4gICAgICBmb3IgKDtcbiAgICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICAgIGtleVNjaGVkW3JdW3RdID0gdGtbal07XG4gICAgICB9XG4gICAgICBpZiAodCA9PSA0KSB7XG4gICAgICAgIHIrKztcbiAgICAgICAgdCA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRoaXMucm91bmRzID0gcm91bmRzO1xuICB0aGlzLnJrID0ga2V5U2NoZWQ7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBBRVNlbmNyeXB0KGJsb2NrLCBjdHgpIHtcbiAgdmFyIHI7XG4gIHZhciB0MCwgdDEsIHQyLCB0MztcblxuICB2YXIgYiA9IHBhY2tCeXRlcyhibG9jayk7XG4gIHZhciByb3VuZHMgPSBjdHgucm91bmRzO1xuICB2YXIgYjAgPSBiWzBdO1xuICB2YXIgYjEgPSBiWzFdO1xuICB2YXIgYjIgPSBiWzJdO1xuICB2YXIgYjMgPSBiWzNdO1xuXG4gIGZvciAociA9IDA7IHIgPCByb3VuZHMgLSAxOyByKyspIHtcbiAgICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdO1xuICAgIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gICAgdDIgPSBiMiBeIGN0eC5ya1tyXVsyXTtcbiAgICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdO1xuXG4gICAgYjAgPSBUMVt0MCAmIDI1NV0gXiBUMlsodDEgPj4gOCkgJiAyNTVdIF4gVDNbKHQyID4+IDE2KSAmIDI1NV0gXiBUNFt0MyA+Pj4gMjRdO1xuICAgIGIxID0gVDFbdDEgJiAyNTVdIF4gVDJbKHQyID4+IDgpICYgMjU1XSBeIFQzWyh0MyA+PiAxNikgJiAyNTVdIF4gVDRbdDAgPj4+IDI0XTtcbiAgICBiMiA9IFQxW3QyICYgMjU1XSBeIFQyWyh0MyA+PiA4KSAmIDI1NV0gXiBUM1sodDAgPj4gMTYpICYgMjU1XSBeIFQ0W3QxID4+PiAyNF07XG4gICAgYjMgPSBUMVt0MyAmIDI1NV0gXiBUMlsodDAgPj4gOCkgJiAyNTVdIF4gVDNbKHQxID4+IDE2KSAmIDI1NV0gXiBUNFt0MiA+Pj4gMjRdO1xuICB9XG5cbiAgLy8gbGFzdCByb3VuZCBpcyBzcGVjaWFsXG4gIHIgPSByb3VuZHMgLSAxO1xuXG4gIHQwID0gYjAgXiBjdHgucmtbcl1bMF07XG4gIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gIHQzID0gYjMgXiBjdHgucmtbcl1bM107XG5cbiAgYlswXSA9IEYxKHQwLCB0MSwgdDIsIHQzKSBeIGN0eC5ya1tyb3VuZHNdWzBdO1xuICBiWzFdID0gRjEodDEsIHQyLCB0MywgdDApIF4gY3R4LnJrW3JvdW5kc11bMV07XG4gIGJbMl0gPSBGMSh0MiwgdDMsIHQwLCB0MSkgXiBjdHgucmtbcm91bmRzXVsyXTtcbiAgYlszXSA9IEYxKHQzLCB0MCwgdDEsIHQyKSBeIGN0eC5ya1tyb3VuZHNdWzNdO1xuXG4gIHJldHVybiB1bnBhY2tCeXRlcyhiKTtcbn1cblxuZnVuY3Rpb24gbWFrZUNsYXNzKGxlbmd0aCkge1xuXG4gIHZhciBjID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5rZXkgPSBrZXlFeHBhbnNpb24oa2V5KTtcblxuICAgIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgICByZXR1cm4gQUVTZW5jcnlwdChibG9jaywgdGhpcy5rZXkpO1xuICAgIH1cbiAgfVxuXG4gIGMuYmxvY2tTaXplID0gYy5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4gIGMua2V5U2l6ZSA9IGMucHJvdG90eXBlLmtleVNpemUgPSBsZW5ndGggLyA4O1xuXG4gIHJldHVybiBjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHt9XG5cbnZhciB0eXBlcyA9IFsxMjgsIDE5MiwgMjU2XTtcblxuZm9yICh2YXIgaSBpbiB0eXBlcykge1xuICBtb2R1bGUuZXhwb3J0c1t0eXBlc1tpXV0gPSBtYWtlQ2xhc3ModHlwZXNbaV0pO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgbmtsZWluIHNvZnR3YXJlIChua2xlaW4uY29tKVxuICovXG5cbi8qKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvYmxvd2Zpc2ggKi9cblxuLyogXG4gKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIEJydWNlIFNjaG5laWVyJ3MgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLlxuICpcbiAqXG4gKiBUaGUgY29uc3RydWN0b3IgZG9lc24ndCBkbyBtdWNoIG9mIGFueXRoaW5nLiAgSXQncyBqdXN0IGhlcmVcbiAqIHNvIHdlIGNhbiBzdGFydCBkZWZpbmluZyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzIGFuZCBzdWNoLlxuICovXG5mdW5jdGlvbiBCbG93ZmlzaCgpIHt9O1xuXG4vKlxuICogRGVjbGFyZSB0aGUgYmxvY2sgc2l6ZSBzbyB0aGF0IHByb3RvY29scyBrbm93IHdoYXQgc2l6ZVxuICogSW5pdGlhbGl6YXRpb24gVmVjdG9yIChJVikgdGhleSB3aWxsIG5lZWQuXG4gKi9cbkJsb3dmaXNoLnByb3RvdHlwZS5CTE9DS1NJWkUgPSA4O1xuXG4vKlxuICogVGhlc2UgYXJlIHRoZSBkZWZhdWx0IFNCT1hFUy5cbiAqL1xuQmxvd2Zpc2gucHJvdG90eXBlLlNCT1hFUyA9IFtcbiAgW1xuICAgICAgMHhkMTMxMGJhNiwgMHg5OGRmYjVhYywgMHgyZmZkNzJkYiwgMHhkMDFhZGZiNywgMHhiOGUxYWZlZCwgMHg2YTI2N2U5NixcbiAgICAgIDB4YmE3YzkwNDUsIDB4ZjEyYzdmOTksIDB4MjRhMTk5NDcsIDB4YjM5MTZjZjcsIDB4MDgwMWYyZTIsIDB4ODU4ZWZjMTYsXG4gICAgICAweDYzNjkyMGQ4LCAweDcxNTc0ZTY5LCAweGE0NThmZWEzLCAweGY0OTMzZDdlLCAweDBkOTU3NDhmLCAweDcyOGViNjU4LFxuICAgICAgMHg3MThiY2Q1OCwgMHg4MjE1NGFlZSwgMHg3YjU0YTQxZCwgMHhjMjVhNTliNSwgMHg5YzMwZDUzOSwgMHgyYWYyNjAxMyxcbiAgICAgIDB4YzVkMWIwMjMsIDB4Mjg2MDg1ZjAsIDB4Y2E0MTc5MTgsIDB4YjhkYjM4ZWYsIDB4OGU3OWRjYjAsIDB4NjAzYTE4MGUsXG4gICAgICAweDZjOWUwZThiLCAweGIwMWU4YTNlLCAweGQ3MTU3N2MxLCAweGJkMzE0YjI3LCAweDc4YWYyZmRhLCAweDU1NjA1YzYwLFxuICAgICAgMHhlNjU1MjVmMywgMHhhYTU1YWI5NCwgMHg1NzQ4OTg2MiwgMHg2M2U4MTQ0MCwgMHg1NWNhMzk2YSwgMHgyYWFiMTBiNixcbiAgICAgIDB4YjRjYzVjMzQsIDB4MTE0MWU4Y2UsIDB4YTE1NDg2YWYsIDB4N2M3MmU5OTMsIDB4YjNlZTE0MTEsIDB4NjM2ZmJjMmEsXG4gICAgICAweDJiYTljNTVkLCAweDc0MTgzMWY2LCAweGNlNWMzZTE2LCAweDliODc5MzFlLCAweGFmZDZiYTMzLCAweDZjMjRjZjVjLFxuICAgICAgMHg3YTMyNTM4MSwgMHgyODk1ODY3NywgMHgzYjhmNDg5OCwgMHg2YjRiYjlhZiwgMHhjNGJmZTgxYiwgMHg2NjI4MjE5MyxcbiAgICAgIDB4NjFkODA5Y2MsIDB4ZmIyMWE5OTEsIDB4NDg3Y2FjNjAsIDB4NWRlYzgwMzIsIDB4ZWY4NDVkNWQsIDB4ZTk4NTc1YjEsXG4gICAgICAweGRjMjYyMzAyLCAweGViNjUxYjg4LCAweDIzODkzZTgxLCAweGQzOTZhY2M1LCAweDBmNmQ2ZmYzLCAweDgzZjQ0MjM5LFxuICAgICAgMHgyZTBiNDQ4MiwgMHhhNDg0MjAwNCwgMHg2OWM4ZjA0YSwgMHg5ZTFmOWI1ZSwgMHgyMWM2Njg0MiwgMHhmNmU5NmM5YSxcbiAgICAgIDB4NjcwYzljNjEsIDB4YWJkMzg4ZjAsIDB4NmE1MWEwZDIsIDB4ZDg1NDJmNjgsIDB4OTYwZmE3MjgsIDB4YWI1MTMzYTMsXG4gICAgICAweDZlZWYwYjZjLCAweDEzN2EzYmU0LCAweGJhM2JmMDUwLCAweDdlZmIyYTk4LCAweGExZjE2NTFkLCAweDM5YWYwMTc2LFxuICAgICAgMHg2NmNhNTkzZSwgMHg4MjQzMGU4OCwgMHg4Y2VlODYxOSwgMHg0NTZmOWZiNCwgMHg3ZDg0YTVjMywgMHgzYjhiNWViZSxcbiAgICAgIDB4ZTA2Zjc1ZDgsIDB4ODVjMTIwNzMsIDB4NDAxYTQ0OWYsIDB4NTZjMTZhYTYsIDB4NGVkM2FhNjIsIDB4MzYzZjc3MDYsXG4gICAgICAweDFiZmVkZjcyLCAweDQyOWIwMjNkLCAweDM3ZDBkNzI0LCAweGQwMGExMjQ4LCAweGRiMGZlYWQzLCAweDQ5ZjFjMDliLFxuICAgICAgMHgwNzUzNzJjOSwgMHg4MDk5MWI3YiwgMHgyNWQ0NzlkOCwgMHhmNmU4ZGVmNywgMHhlM2ZlNTAxYSwgMHhiNjc5NGMzYixcbiAgICAgIDB4OTc2Y2UwYmQsIDB4MDRjMDA2YmEsIDB4YzFhOTRmYjYsIDB4NDA5ZjYwYzQsIDB4NWU1YzllYzIsIDB4MTk2YTI0NjMsXG4gICAgICAweDY4ZmI2ZmFmLCAweDNlNmM1M2I1LCAweDEzMzliMmViLCAweDNiNTJlYzZmLCAweDZkZmM1MTFmLCAweDliMzA5NTJjLFxuICAgICAgMHhjYzgxNDU0NCwgMHhhZjVlYmQwOSwgMHhiZWUzZDAwNCwgMHhkZTMzNGFmZCwgMHg2NjBmMjgwNywgMHgxOTJlNGJiMyxcbiAgICAgIDB4YzBjYmE4NTcsIDB4NDVjODc0MGYsIDB4ZDIwYjVmMzksIDB4YjlkM2ZiZGIsIDB4NTU3OWMwYmQsIDB4MWE2MDMyMGEsXG4gICAgICAweGQ2YTEwMGM2LCAweDQwMmM3Mjc5LCAweDY3OWYyNWZlLCAweGZiMWZhM2NjLCAweDhlYTVlOWY4LCAweGRiMzIyMmY4LFxuICAgICAgMHgzYzc1MTZkZiwgMHhmZDYxNmIxNSwgMHgyZjUwMWVjOCwgMHhhZDA1NTJhYiwgMHgzMjNkYjVmYSwgMHhmZDIzODc2MCxcbiAgICAgIDB4NTMzMTdiNDgsIDB4M2UwMGRmODIsIDB4OWU1YzU3YmIsIDB4Y2E2ZjhjYTAsIDB4MWE4NzU2MmUsIDB4ZGYxNzY5ZGIsXG4gICAgICAweGQ1NDJhOGY2LCAweDI4N2VmZmMzLCAweGFjNjczMmM2LCAweDhjNGY1NTczLCAweDY5NWIyN2IwLCAweGJiY2E1OGM4LFxuICAgICAgMHhlMWZmYTM1ZCwgMHhiOGYwMTFhMCwgMHgxMGZhM2Q5OCwgMHhmZDIxODNiOCwgMHg0YWZjYjU2YywgMHgyZGQxZDM1YixcbiAgICAgIDB4OWE1M2U0NzksIDB4YjZmODQ1NjUsIDB4ZDI4ZTQ5YmMsIDB4NGJmYjk3OTAsIDB4ZTFkZGYyZGEsIDB4YTRjYjdlMzMsXG4gICAgICAweDYyZmIxMzQxLCAweGNlZTRjNmU4LCAweGVmMjBjYWRhLCAweDM2Nzc0YzAxLCAweGQwN2U5ZWZlLCAweDJiZjExZmI0LFxuICAgICAgMHg5NWRiZGE0ZCwgMHhhZTkwOTE5OCwgMHhlYWFkOGU3MSwgMHg2YjkzZDVhMCwgMHhkMDhlZDFkMCwgMHhhZmM3MjVlMCxcbiAgICAgIDB4OGUzYzViMmYsIDB4OGU3NTk0YjcsIDB4OGZmNmUyZmIsIDB4ZjIxMjJiNjQsIDB4ODg4OGI4MTIsIDB4OTAwZGYwMWMsXG4gICAgICAweDRmYWQ1ZWEwLCAweDY4OGZjMzFjLCAweGQxY2ZmMTkxLCAweGIzYThjMWFkLCAweDJmMmYyMjE4LCAweGJlMGUxNzc3LFxuICAgICAgMHhlYTc1MmRmZSwgMHg4YjAyMWZhMSwgMHhlNWEwY2MwZiwgMHhiNTZmNzRlOCwgMHgxOGFjZjNkNiwgMHhjZTg5ZTI5OSxcbiAgICAgIDB4YjRhODRmZTAsIDB4ZmQxM2UwYjcsIDB4N2NjNDNiODEsIDB4ZDJhZGE4ZDksIDB4MTY1ZmEyNjYsIDB4ODA5NTc3MDUsXG4gICAgICAweDkzY2M3MzE0LCAweDIxMWExNDc3LCAweGU2YWQyMDY1LCAweDc3YjVmYTg2LCAweGM3NTQ0MmY1LCAweGZiOWQzNWNmLFxuICAgICAgMHhlYmNkYWYwYywgMHg3YjNlODlhMCwgMHhkNjQxMWJkMywgMHhhZTFlN2U0OSwgMHgwMDI1MGUyZCwgMHgyMDcxYjM1ZSxcbiAgICAgIDB4MjI2ODAwYmIsIDB4NTdiOGUwYWYsIDB4MjQ2NDM2OWIsIDB4ZjAwOWI5MWUsIDB4NTU2MzkxMWQsIDB4NTlkZmE2YWEsXG4gICAgICAweDc4YzE0Mzg5LCAweGQ5NWE1MzdmLCAweDIwN2Q1YmEyLCAweDAyZTViOWM1LCAweDgzMjYwMzc2LCAweDYyOTVjZmE5LFxuICAgICAgMHgxMWM4MTk2OCwgMHg0ZTczNGE0MSwgMHhiMzQ3MmRjYSwgMHg3YjE0YTk0YSwgMHgxYjUxMDA1MiwgMHg5YTUzMjkxNSxcbiAgICAgIDB4ZDYwZjU3M2YsIDB4YmM5YmM2ZTQsIDB4MmI2MGE0NzYsIDB4ODFlNjc0MDAsIDB4MDhiYTZmYjUsIDB4NTcxYmU5MWYsXG4gICAgICAweGYyOTZlYzZiLCAweDJhMGRkOTE1LCAweGI2NjM2NTIxLCAweGU3YjlmOWI2LCAweGZmMzQwNTJlLCAweGM1ODU1NjY0LFxuICAgICAgMHg1M2IwMmQ1ZCwgMHhhOTlmOGZhMSwgMHgwOGJhNDc5OSwgMHg2ZTg1MDc2YVxuICBdLFxuICBbXG4gICAgICAweDRiN2E3MGU5LCAweGI1YjMyOTQ0LCAweGRiNzUwOTJlLCAweGM0MTkyNjIzLCAweGFkNmVhNmIwLCAweDQ5YTdkZjdkLFxuICAgICAgMHg5Y2VlNjBiOCwgMHg4ZmVkYjI2NiwgMHhlY2FhOGM3MSwgMHg2OTlhMTdmZiwgMHg1NjY0NTI2YywgMHhjMmIxOWVlMSxcbiAgICAgIDB4MTkzNjAyYTUsIDB4NzUwOTRjMjksIDB4YTA1OTEzNDAsIDB4ZTQxODNhM2UsIDB4M2Y1NDk4OWEsIDB4NWI0MjlkNjUsXG4gICAgICAweDZiOGZlNGQ2LCAweDk5ZjczZmQ2LCAweGExZDI5YzA3LCAweGVmZTgzMGY1LCAweDRkMmQzOGU2LCAweGYwMjU1ZGMxLFxuICAgICAgMHg0Y2RkMjA4NiwgMHg4NDcwZWIyNiwgMHg2MzgyZTljNiwgMHgwMjFlY2M1ZSwgMHgwOTY4NmIzZiwgMHgzZWJhZWZjOSxcbiAgICAgIDB4M2M5NzE4MTQsIDB4NmI2YTcwYTEsIDB4Njg3ZjM1ODQsIDB4NTJhMGUyODYsIDB4Yjc5YzUzMDUsIDB4YWE1MDA3MzcsXG4gICAgICAweDNlMDc4NDFjLCAweDdmZGVhZTVjLCAweDhlN2Q0NGVjLCAweDU3MTZmMmI4LCAweGIwM2FkYTM3LCAweGYwNTAwYzBkLFxuICAgICAgMHhmMDFjMWYwNCwgMHgwMjAwYjNmZiwgMHhhZTBjZjUxYSwgMHgzY2I1NzRiMiwgMHgyNTgzN2E1OCwgMHhkYzA5MjFiZCxcbiAgICAgIDB4ZDE5MTEzZjksIDB4N2NhOTJmZjYsIDB4OTQzMjQ3NzMsIDB4MjJmNTQ3MDEsIDB4M2FlNWU1ODEsIDB4MzdjMmRhZGMsXG4gICAgICAweGM4YjU3NjM0LCAweDlhZjNkZGE3LCAweGE5NDQ2MTQ2LCAweDBmZDAwMzBlLCAweGVjYzhjNzNlLCAweGE0NzUxZTQxLFxuICAgICAgMHhlMjM4Y2Q5OSwgMHgzYmVhMGUyZiwgMHgzMjgwYmJhMSwgMHgxODNlYjMzMSwgMHg0ZTU0OGIzOCwgMHg0ZjZkYjkwOCxcbiAgICAgIDB4NmY0MjBkMDMsIDB4ZjYwYTA0YmYsIDB4MmNiODEyOTAsIDB4MjQ5NzdjNzksIDB4NTY3OWIwNzIsIDB4YmNhZjg5YWYsXG4gICAgICAweGRlOWE3NzFmLCAweGQ5OTMwODEwLCAweGIzOGJhZTEyLCAweGRjY2YzZjJlLCAweDU1MTI3MjFmLCAweDJlNmI3MTI0LFxuICAgICAgMHg1MDFhZGRlNiwgMHg5Zjg0Y2Q4NywgMHg3YTU4NDcxOCwgMHg3NDA4ZGExNywgMHhiYzlmOWFiYywgMHhlOTRiN2Q4YyxcbiAgICAgIDB4ZWM3YWVjM2EsIDB4ZGI4NTFkZmEsIDB4NjMwOTQzNjYsIDB4YzQ2NGMzZDIsIDB4ZWYxYzE4NDcsIDB4MzIxNWQ5MDgsXG4gICAgICAweGRkNDMzYjM3LCAweDI0YzJiYTE2LCAweDEyYTE0ZDQzLCAweDJhNjVjNDUxLCAweDUwOTQwMDAyLCAweDEzM2FlNGRkLFxuICAgICAgMHg3MWRmZjg5ZSwgMHgxMDMxNGU1NSwgMHg4MWFjNzdkNiwgMHg1ZjExMTk5YiwgMHgwNDM1NTZmMSwgMHhkN2EzYzc2YixcbiAgICAgIDB4M2MxMTE4M2IsIDB4NTkyNGE1MDksIDB4ZjI4ZmU2ZWQsIDB4OTdmMWZiZmEsIDB4OWViYWJmMmMsIDB4MWUxNTNjNmUsXG4gICAgICAweDg2ZTM0NTcwLCAweGVhZTk2ZmIxLCAweDg2MGU1ZTBhLCAweDVhM2UyYWIzLCAweDc3MWZlNzFjLCAweDRlM2QwNmZhLFxuICAgICAgMHgyOTY1ZGNiOSwgMHg5OWU3MWQwZiwgMHg4MDNlODlkNiwgMHg1MjY2YzgyNSwgMHgyZTRjYzk3OCwgMHg5YzEwYjM2YSxcbiAgICAgIDB4YzYxNTBlYmEsIDB4OTRlMmVhNzgsIDB4YTVmYzNjNTMsIDB4MWUwYTJkZjQsIDB4ZjJmNzRlYTcsIDB4MzYxZDJiM2QsXG4gICAgICAweDE5MzkyNjBmLCAweDE5YzI3OTYwLCAweDUyMjNhNzA4LCAweGY3MTMxMmI2LCAweGViYWRmZTZlLCAweGVhYzMxZjY2LFxuICAgICAgMHhlM2JjNDU5NSwgMHhhNjdiYzg4MywgMHhiMTdmMzdkMSwgMHgwMThjZmYyOCwgMHhjMzMyZGRlZiwgMHhiZTZjNWFhNSxcbiAgICAgIDB4NjU1ODIxODUsIDB4NjhhYjk4MDIsIDB4ZWVjZWE1MGYsIDB4ZGIyZjk1M2IsIDB4MmFlZjdkYWQsIDB4NWI2ZTJmODQsXG4gICAgICAweDE1MjFiNjI4LCAweDI5MDc2MTcwLCAweGVjZGQ0Nzc1LCAweDYxOWYxNTEwLCAweDEzY2NhODMwLCAweGViNjFiZDk2LFxuICAgICAgMHgwMzM0ZmUxZSwgMHhhYTAzNjNjZiwgMHhiNTczNWM5MCwgMHg0YzcwYTIzOSwgMHhkNTllOWUwYiwgMHhjYmFhZGUxNCxcbiAgICAgIDB4ZWVjYzg2YmMsIDB4NjA2MjJjYTcsIDB4OWNhYjVjYWIsIDB4YjJmMzg0NmUsIDB4NjQ4YjFlYWYsIDB4MTliZGYwY2EsXG4gICAgICAweGEwMjM2OWI5LCAweDY1NWFiYjUwLCAweDQwNjg1YTMyLCAweDNjMmFiNGIzLCAweDMxOWVlOWQ1LCAweGMwMjFiOGY3LFxuICAgICAgMHg5YjU0MGIxOSwgMHg4NzVmYTA5OSwgMHg5NWY3OTk3ZSwgMHg2MjNkN2RhOCwgMHhmODM3ODg5YSwgMHg5N2UzMmQ3NyxcbiAgICAgIDB4MTFlZDkzNWYsIDB4MTY2ODEyODEsIDB4MGUzNTg4MjksIDB4YzdlNjFmZDYsIDB4OTZkZWRmYTEsIDB4Nzg1OGJhOTksXG4gICAgICAweDU3ZjU4NGE1LCAweDFiMjI3MjYzLCAweDliODNjM2ZmLCAweDFhYzI0Njk2LCAweGNkYjMwYWViLCAweDUzMmUzMDU0LFxuICAgICAgMHg4ZmQ5NDhlNCwgMHg2ZGJjMzEyOCwgMHg1OGViZjJlZiwgMHgzNGM2ZmZlYSwgMHhmZTI4ZWQ2MSwgMHhlZTdjM2M3MyxcbiAgICAgIDB4NWQ0YTE0ZDksIDB4ZTg2NGI3ZTMsIDB4NDIxMDVkMTQsIDB4MjAzZTEzZTAsIDB4NDVlZWUyYjYsIDB4YTNhYWFiZWEsXG4gICAgICAweGRiNmM0ZjE1LCAweGZhY2I0ZmQwLCAweGM3NDJmNDQyLCAweGVmNmFiYmI1LCAweDY1NGYzYjFkLCAweDQxY2QyMTA1LFxuICAgICAgMHhkODFlNzk5ZSwgMHg4Njg1NGRjNywgMHhlNDRiNDc2YSwgMHgzZDgxNjI1MCwgMHhjZjYyYTFmMiwgMHg1YjhkMjY0NixcbiAgICAgIDB4ZmM4ODgzYTAsIDB4YzFjN2I2YTMsIDB4N2YxNTI0YzMsIDB4NjljYjc0OTIsIDB4NDc4NDhhMGIsIDB4NTY5MmIyODUsXG4gICAgICAweDA5NWJiZjAwLCAweGFkMTk0ODlkLCAweDE0NjJiMTc0LCAweDIzODIwZTAwLCAweDU4NDI4ZDJhLCAweDBjNTVmNWVhLFxuICAgICAgMHgxZGFkZjQzZSwgMHgyMzNmNzA2MSwgMHgzMzcyZjA5MiwgMHg4ZDkzN2U0MSwgMHhkNjVmZWNmMSwgMHg2YzIyM2JkYixcbiAgICAgIDB4N2NkZTM3NTksIDB4Y2JlZTc0NjAsIDB4NDA4NWYyYTcsIDB4Y2U3NzMyNmUsIDB4YTYwNzgwODQsIDB4MTlmODUwOWUsXG4gICAgICAweGU4ZWZkODU1LCAweDYxZDk5NzM1LCAweGE5NjlhN2FhLCAweGM1MGMwNmMyLCAweDVhMDRhYmZjLCAweDgwMGJjYWRjLFxuICAgICAgMHg5ZTQ0N2EyZSwgMHhjMzQ1MzQ4NCwgMHhmZGQ1NjcwNSwgMHgwZTFlOWVjOSwgMHhkYjczZGJkMywgMHgxMDU1ODhjZCxcbiAgICAgIDB4Njc1ZmRhNzksIDB4ZTM2NzQzNDAsIDB4YzVjNDM0NjUsIDB4NzEzZTM4ZDgsIDB4M2QyOGY4OWUsIDB4ZjE2ZGZmMjAsXG4gICAgICAweDE1M2UyMWU3LCAweDhmYjAzZDRhLCAweGU2ZTM5ZjJiLCAweGRiODNhZGY3XG4gIF0sXG4gIFtcbiAgICAgIDB4ZTkzZDVhNjgsIDB4OTQ4MTQwZjcsIDB4ZjY0YzI2MWMsIDB4OTQ2OTI5MzQsIDB4NDExNTIwZjcsIDB4NzYwMmQ0ZjcsXG4gICAgICAweGJjZjQ2YjJlLCAweGQ0YTIwMDY4LCAweGQ0MDgyNDcxLCAweDMzMjBmNDZhLCAweDQzYjdkNGI3LCAweDUwMDA2MWFmLFxuICAgICAgMHgxZTM5ZjYyZSwgMHg5NzI0NDU0NiwgMHgxNDIxNGY3NCwgMHhiZjhiODg0MCwgMHg0ZDk1ZmMxZCwgMHg5NmI1OTFhZixcbiAgICAgIDB4NzBmNGRkZDMsIDB4NjZhMDJmNDUsIDB4YmZiYzA5ZWMsIDB4MDNiZDk3ODUsIDB4N2ZhYzZkZDAsIDB4MzFjYjg1MDQsXG4gICAgICAweDk2ZWIyN2IzLCAweDU1ZmQzOTQxLCAweGRhMjU0N2U2LCAweGFiY2EwYTlhLCAweDI4NTA3ODI1LCAweDUzMDQyOWY0LFxuICAgICAgMHgwYTJjODZkYSwgMHhlOWI2NmRmYiwgMHg2OGRjMTQ2MiwgMHhkNzQ4NjkwMCwgMHg2ODBlYzBhNCwgMHgyN2ExOGRlZSxcbiAgICAgIDB4NGYzZmZlYTIsIDB4ZTg4N2FkOGMsIDB4YjU4Y2UwMDYsIDB4N2FmNGQ2YjYsIDB4YWFjZTFlN2MsIDB4ZDMzNzVmZWMsXG4gICAgICAweGNlNzhhMzk5LCAweDQwNmIyYTQyLCAweDIwZmU5ZTM1LCAweGQ5ZjM4NWI5LCAweGVlMzlkN2FiLCAweDNiMTI0ZThiLFxuICAgICAgMHgxZGM5ZmFmNywgMHg0YjZkMTg1NiwgMHgyNmEzNjYzMSwgMHhlYWUzOTdiMiwgMHgzYTZlZmE3NCwgMHhkZDViNDMzMixcbiAgICAgIDB4Njg0MWU3ZjcsIDB4Y2E3ODIwZmIsIDB4ZmIwYWY1NGUsIDB4ZDhmZWIzOTcsIDB4NDU0MDU2YWMsIDB4YmE0ODk1MjcsXG4gICAgICAweDU1NTMzYTNhLCAweDIwODM4ZDg3LCAweGZlNmJhOWI3LCAweGQwOTY5NTRiLCAweDU1YTg2N2JjLCAweGExMTU5YTU4LFxuICAgICAgMHhjY2E5Mjk2MywgMHg5OWUxZGIzMywgMHhhNjJhNGE1NiwgMHgzZjMxMjVmOSwgMHg1ZWY0N2UxYywgMHg5MDI5MzE3YyxcbiAgICAgIDB4ZmRmOGU4MDIsIDB4MDQyNzJmNzAsIDB4ODBiYjE1NWMsIDB4MDUyODJjZTMsIDB4OTVjMTE1NDgsIDB4ZTRjNjZkMjIsXG4gICAgICAweDQ4YzExMzNmLCAweGM3MGY4NmRjLCAweDA3ZjljOWVlLCAweDQxMDQxZjBmLCAweDQwNDc3OWE0LCAweDVkODg2ZTE3LFxuICAgICAgMHgzMjVmNTFlYiwgMHhkNTliYzBkMSwgMHhmMmJjYzE4ZiwgMHg0MTExMzU2NCwgMHgyNTdiNzgzNCwgMHg2MDJhOWM2MCxcbiAgICAgIDB4ZGZmOGU4YTMsIDB4MWY2MzZjMWIsIDB4MGUxMmI0YzIsIDB4MDJlMTMyOWUsIDB4YWY2NjRmZDEsIDB4Y2FkMTgxMTUsXG4gICAgICAweDZiMjM5NWUwLCAweDMzM2U5MmUxLCAweDNiMjQwYjYyLCAweGVlYmViOTIyLCAweDg1YjJhMjBlLCAweGU2YmEwZDk5LFxuICAgICAgMHhkZTcyMGM4YywgMHgyZGEyZjcyOCwgMHhkMDEyNzg0NSwgMHg5NWI3OTRmZCwgMHg2NDdkMDg2MiwgMHhlN2NjZjVmMCxcbiAgICAgIDB4NTQ0OWEzNmYsIDB4ODc3ZDQ4ZmEsIDB4YzM5ZGZkMjcsIDB4ZjMzZThkMWUsIDB4MGE0NzYzNDEsIDB4OTkyZWZmNzQsXG4gICAgICAweDNhNmY2ZWFiLCAweGY0ZjhmZDM3LCAweGE4MTJkYzYwLCAweGExZWJkZGY4LCAweDk5MWJlMTRjLCAweGRiNmU2YjBkLFxuICAgICAgMHhjNjdiNTUxMCwgMHg2ZDY3MmMzNywgMHgyNzY1ZDQzYiwgMHhkY2QwZTgwNCwgMHhmMTI5MGRjNywgMHhjYzAwZmZhMyxcbiAgICAgIDB4YjUzOTBmOTIsIDB4NjkwZmVkMGIsIDB4NjY3YjlmZmIsIDB4Y2VkYjdkOWMsIDB4YTA5MWNmMGIsIDB4ZDkxNTVlYTMsXG4gICAgICAweGJiMTMyZjg4LCAweDUxNWJhZDI0LCAweDdiOTQ3OWJmLCAweDc2M2JkNmViLCAweDM3MzkyZWIzLCAweGNjMTE1OTc5LFxuICAgICAgMHg4MDI2ZTI5NywgMHhmNDJlMzEyZCwgMHg2ODQyYWRhNywgMHhjNjZhMmIzYiwgMHgxMjc1NGNjYywgMHg3ODJlZjExYyxcbiAgICAgIDB4NmExMjQyMzcsIDB4Yjc5MjUxZTcsIDB4MDZhMWJiZTYsIDB4NGJmYjYzNTAsIDB4MWE2YjEwMTgsIDB4MTFjYWVkZmEsXG4gICAgICAweDNkMjViZGQ4LCAweGUyZTFjM2M5LCAweDQ0NDIxNjU5LCAweDBhMTIxMzg2LCAweGQ5MGNlYzZlLCAweGQ1YWJlYTJhLFxuICAgICAgMHg2NGFmNjc0ZSwgMHhkYTg2YTg1ZiwgMHhiZWJmZTk4OCwgMHg2NGU0YzNmZSwgMHg5ZGJjODA1NywgMHhmMGY3YzA4NixcbiAgICAgIDB4NjA3ODdiZjgsIDB4NjAwMzYwNGQsIDB4ZDFmZDgzNDYsIDB4ZjYzODFmYjAsIDB4Nzc0NWFlMDQsIDB4ZDczNmZjY2MsXG4gICAgICAweDgzNDI2YjMzLCAweGYwMWVhYjcxLCAweGIwODA0MTg3LCAweDNjMDA1ZTVmLCAweDc3YTA1N2JlLCAweGJkZThhZTI0LFxuICAgICAgMHg1NTQ2NDI5OSwgMHhiZjU4MmU2MSwgMHg0ZTU4ZjQ4ZiwgMHhmMmRkZmRhMiwgMHhmNDc0ZWYzOCwgMHg4Nzg5YmRjMixcbiAgICAgIDB4NTM2NmY5YzMsIDB4YzhiMzhlNzQsIDB4YjQ3NWYyNTUsIDB4NDZmY2Q5YjksIDB4N2FlYjI2NjEsIDB4OGIxZGRmODQsXG4gICAgICAweDg0NmEwZTc5LCAweDkxNWY5NWUyLCAweDQ2NmU1OThlLCAweDIwYjQ1NzcwLCAweDhjZDU1NTkxLCAweGM5MDJkZTRjLFxuICAgICAgMHhiOTBiYWNlMSwgMHhiYjgyMDVkMCwgMHgxMWE4NjI0OCwgMHg3NTc0YTk5ZSwgMHhiNzdmMTliNiwgMHhlMGE5ZGMwOSxcbiAgICAgIDB4NjYyZDA5YTEsIDB4YzQzMjQ2MzMsIDB4ZTg1YTFmMDIsIDB4MDlmMGJlOGMsIDB4NGE5OWEwMjUsIDB4MWQ2ZWZlMTAsXG4gICAgICAweDFhYjkzZDFkLCAweDBiYTVhNGRmLCAweGExODZmMjBmLCAweDI4NjhmMTY5LCAweGRjYjdkYTgzLCAweDU3MzkwNmZlLFxuICAgICAgMHhhMWUyY2U5YiwgMHg0ZmNkN2Y1MiwgMHg1MDExNWUwMSwgMHhhNzA2ODNmYSwgMHhhMDAyYjVjNCwgMHgwZGU2ZDAyNyxcbiAgICAgIDB4OWFmODhjMjcsIDB4NzczZjg2NDEsIDB4YzM2MDRjMDYsIDB4NjFhODA2YjUsIDB4ZjAxNzdhMjgsIDB4YzBmNTg2ZTAsXG4gICAgICAweDAwNjA1OGFhLCAweDMwZGM3ZDYyLCAweDExZTY5ZWQ3LCAweDIzMzhlYTYzLCAweDUzYzJkZDk0LCAweGMyYzIxNjM0LFxuICAgICAgMHhiYmNiZWU1NiwgMHg5MGJjYjZkZSwgMHhlYmZjN2RhMSwgMHhjZTU5MWQ3NiwgMHg2ZjA1ZTQwOSwgMHg0YjdjMDE4OCxcbiAgICAgIDB4Mzk3MjBhM2QsIDB4N2M5MjdjMjQsIDB4ODZlMzcyNWYsIDB4NzI0ZDlkYjksIDB4MWFjMTViYjQsIDB4ZDM5ZWI4ZmMsXG4gICAgICAweGVkNTQ1NTc4LCAweDA4ZmNhNWI1LCAweGQ4M2Q3Y2QzLCAweDRkYWQwZmM0LCAweDFlNTBlZjVlLCAweGIxNjFlNmY4LFxuICAgICAgMHhhMjg1MTRkOSwgMHg2YzUxMTMzYywgMHg2ZmQ1YzdlNywgMHg1NmUxNGVjNCwgMHgzNjJhYmZjZSwgMHhkZGM2YzgzNyxcbiAgICAgIDB4ZDc5YTMyMzQsIDB4OTI2MzgyMTIsIDB4NjcwZWZhOGUsIDB4NDA2MDAwZTBcbiAgXSxcbiAgW1xuICAgICAgMHgzYTM5Y2UzNywgMHhkM2ZhZjVjZiwgMHhhYmMyNzczNywgMHg1YWM1MmQxYiwgMHg1Y2IwNjc5ZSwgMHg0ZmEzMzc0MixcbiAgICAgIDB4ZDM4MjI3NDAsIDB4OTliYzliYmUsIDB4ZDUxMThlOWQsIDB4YmYwZjczMTUsIDB4ZDYyZDFjN2UsIDB4YzcwMGM0N2IsXG4gICAgICAweGI3OGMxYjZiLCAweDIxYTE5MDQ1LCAweGIyNmViMWJlLCAweDZhMzY2ZWI0LCAweDU3NDhhYjJmLCAweGJjOTQ2ZTc5LFxuICAgICAgMHhjNmEzNzZkMiwgMHg2NTQ5YzJjOCwgMHg1MzBmZjhlZSwgMHg0NjhkZGU3ZCwgMHhkNTczMGExZCwgMHg0Y2QwNGRjNixcbiAgICAgIDB4MjkzOWJiZGIsIDB4YTliYTQ2NTAsIDB4YWM5NTI2ZTgsIDB4YmU1ZWUzMDQsIDB4YTFmYWQ1ZjAsIDB4NmEyZDUxOWEsXG4gICAgICAweDYzZWY4Y2UyLCAweDlhODZlZTIyLCAweGMwODljMmI4LCAweDQzMjQyZWY2LCAweGE1MWUwM2FhLCAweDljZjJkMGE0LFxuICAgICAgMHg4M2MwNjFiYSwgMHg5YmU5NmE0ZCwgMHg4ZmU1MTU1MCwgMHhiYTY0NWJkNiwgMHgyODI2YTJmOSwgMHhhNzNhM2FlMSxcbiAgICAgIDB4NGJhOTk1ODYsIDB4ZWY1NTYyZTksIDB4YzcyZmVmZDMsIDB4Zjc1MmY3ZGEsIDB4M2YwNDZmNjksIDB4NzdmYTBhNTksXG4gICAgICAweDgwZTRhOTE1LCAweDg3YjA4NjAxLCAweDliMDllNmFkLCAweDNiM2VlNTkzLCAweGU5OTBmZDVhLCAweDllMzRkNzk3LFxuICAgICAgMHgyY2YwYjdkOSwgMHgwMjJiOGI1MSwgMHg5NmQ1YWMzYSwgMHgwMTdkYTY3ZCwgMHhkMWNmM2VkNiwgMHg3YzdkMmQyOCxcbiAgICAgIDB4MWY5ZjI1Y2YsIDB4YWRmMmI4OWIsIDB4NWFkNmI0NzIsIDB4NWE4OGY1NGMsIDB4ZTAyOWFjNzEsIDB4ZTAxOWE1ZTYsXG4gICAgICAweDQ3YjBhY2ZkLCAweGVkOTNmYTliLCAweGU4ZDNjNDhkLCAweDI4M2I1N2NjLCAweGY4ZDU2NjI5LCAweDc5MTMyZTI4LFxuICAgICAgMHg3ODVmMDE5MSwgMHhlZDc1NjA1NSwgMHhmNzk2MGU0NCwgMHhlM2QzNWU4YywgMHgxNTA1NmRkNCwgMHg4OGY0NmRiYSxcbiAgICAgIDB4MDNhMTYxMjUsIDB4MDU2NGYwYmQsIDB4YzNlYjllMTUsIDB4M2M5MDU3YTIsIDB4OTcyNzFhZWMsIDB4YTkzYTA3MmEsXG4gICAgICAweDFiM2Y2ZDliLCAweDFlNjMyMWY1LCAweGY1OWM2NmZiLCAweDI2ZGNmMzE5LCAweDc1MzNkOTI4LCAweGIxNTVmZGY1LFxuICAgICAgMHgwMzU2MzQ4MiwgMHg4YWJhM2NiYiwgMHgyODUxNzcxMSwgMHhjMjBhZDlmOCwgMHhhYmNjNTE2NywgMHhjY2FkOTI1ZixcbiAgICAgIDB4NGRlODE3NTEsIDB4MzgzMGRjOGUsIDB4Mzc5ZDU4NjIsIDB4OTMyMGY5OTEsIDB4ZWE3YTkwYzIsIDB4ZmIzZTdiY2UsXG4gICAgICAweDUxMjFjZTY0LCAweDc3NGZiZTMyLCAweGE4YjZlMzdlLCAweGMzMjkzZDQ2LCAweDQ4ZGU1MzY5LCAweDY0MTNlNjgwLFxuICAgICAgMHhhMmFlMDgxMCwgMHhkZDZkYjIyNCwgMHg2OTg1MmRmZCwgMHgwOTA3MjE2NiwgMHhiMzlhNDYwYSwgMHg2NDQ1YzBkZCxcbiAgICAgIDB4NTg2Y2RlY2YsIDB4MWMyMGM4YWUsIDB4NWJiZWY3ZGQsIDB4MWI1ODhkNDAsIDB4Y2NkMjAxN2YsIDB4NmJiNGUzYmIsXG4gICAgICAweGRkYTI2YTdlLCAweDNhNTlmZjQ1LCAweDNlMzUwYTQ0LCAweGJjYjRjZGQ1LCAweDcyZWFjZWE4LCAweGZhNjQ4NGJiLFxuICAgICAgMHg4ZDY2MTJhZSwgMHhiZjNjNmY0NywgMHhkMjliZTQ2MywgMHg1NDJmNWQ5ZSwgMHhhZWMyNzcxYiwgMHhmNjRlNjM3MCxcbiAgICAgIDB4NzQwZTBkOGQsIDB4ZTc1YjEzNTcsIDB4Zjg3MjE2NzEsIDB4YWY1MzdkNWQsIDB4NDA0MGNiMDgsIDB4NGViNGUyY2MsXG4gICAgICAweDM0ZDI0NjZhLCAweDAxMTVhZjg0LCAweGUxYjAwNDI4LCAweDk1OTgzYTFkLCAweDA2Yjg5ZmI0LCAweGNlNmVhMDQ4LFxuICAgICAgMHg2ZjNmM2I4MiwgMHgzNTIwYWI4MiwgMHgwMTFhMWQ0YiwgMHgyNzcyMjdmOCwgMHg2MTE1NjBiMSwgMHhlNzkzM2ZkYyxcbiAgICAgIDB4YmIzYTc5MmIsIDB4MzQ0NTI1YmQsIDB4YTA4ODM5ZTEsIDB4NTFjZTc5NGIsIDB4MmYzMmM5YjcsIDB4YTAxZmJhYzksXG4gICAgICAweGUwMWNjODdlLCAweGJjYzdkMWY2LCAweGNmMDExMWMzLCAweGExZThhYWM3LCAweDFhOTA4NzQ5LCAweGQ0NGZiZDlhLFxuICAgICAgMHhkMGRhZGVjYiwgMHhkNTBhZGEzOCwgMHgwMzM5YzMyYSwgMHhjNjkxMzY2NywgMHg4ZGY5MzE3YywgMHhlMGIxMmI0ZixcbiAgICAgIDB4Zjc5ZTU5YjcsIDB4NDNmNWJiM2EsIDB4ZjJkNTE5ZmYsIDB4MjdkOTQ1OWMsIDB4YmY5NzIyMmMsIDB4MTVlNmZjMmEsXG4gICAgICAweDBmOTFmYzcxLCAweDliOTQxNTI1LCAweGZhZTU5MzYxLCAweGNlYjY5Y2ViLCAweGMyYTg2NDU5LCAweDEyYmFhOGQxLFxuICAgICAgMHhiNmMxMDc1ZSwgMHhlMzA1NmEwYywgMHgxMGQyNTA2NSwgMHhjYjAzYTQ0MiwgMHhlMGVjNmUwZSwgMHgxNjk4ZGIzYixcbiAgICAgIDB4NGM5OGEwYmUsIDB4MzI3OGU5NjQsIDB4OWYxZjk1MzIsIDB4ZTBkMzkyZGYsIDB4ZDNhMDM0MmIsIDB4ODk3MWYyMWUsXG4gICAgICAweDFiMGE3NDQxLCAweDRiYTMzNDhjLCAweGM1YmU3MTIwLCAweGMzNzYzMmQ4LCAweGRmMzU5ZjhkLCAweDliOTkyZjJlLFxuICAgICAgMHhlNjBiNmY0NywgMHgwZmUzZjExZCwgMHhlNTRjZGE1NCwgMHgxZWRhZDg5MSwgMHhjZTYyNzljZiwgMHhjZDNlN2U2ZixcbiAgICAgIDB4MTYxOGIxNjYsIDB4ZmQyYzFkMDUsIDB4ODQ4ZmQyYzUsIDB4ZjZmYjIyOTksIDB4ZjUyM2YzNTcsIDB4YTYzMjc2MjMsXG4gICAgICAweDkzYTgzNTMxLCAweDU2Y2NjZDAyLCAweGFjZjA4MTYyLCAweDVhNzVlYmI1LCAweDZlMTYzNjk3LCAweDg4ZDI3M2NjLFxuICAgICAgMHhkZTk2NjI5MiwgMHg4MWI5NDlkMCwgMHg0YzUwOTAxYiwgMHg3MWM2NTYxNCwgMHhlNmM2YzdiZCwgMHgzMjdhMTQwYSxcbiAgICAgIDB4NDVlMWQwMDYsIDB4YzNmMjdiOWEsIDB4YzlhYTUzZmQsIDB4NjJhODBmMDAsIDB4YmIyNWJmZTIsIDB4MzViZGQyZjYsXG4gICAgICAweDcxMTI2OTA1LCAweGIyMDQwMjIyLCAweGI2Y2JjZjdjLCAweGNkNzY5YzJiLCAweDUzMTEzZWMwLCAweDE2NDBlM2QzLFxuICAgICAgMHgzOGFiYmQ2MCwgMHgyNTQ3YWRmMCwgMHhiYTM4MjA5YywgMHhmNzQ2Y2U3NiwgMHg3N2FmYTFjNSwgMHgyMDc1NjA2MCxcbiAgICAgIDB4ODVjYmZlNGUsIDB4OGFlODhkZDgsIDB4N2FhYWY5YjAsIDB4NGNmOWFhN2UsIDB4MTk0OGMyNWMsIDB4MDJmYjhhOGMsXG4gICAgICAweDAxYzM2YWU0LCAweGQ2ZWJlMWY5LCAweDkwZDRmODY5LCAweGE2NWNkZWEwLCAweDNmMDkyNTJkLCAweGMyMDhlNjlmLFxuICAgICAgMHhiNzRlNjEzMiwgMHhjZTc3ZTI1YiwgMHg1NzhmZGZlMywgMHgzYWMzNzJlNlxuICBdXG5dO1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBkZWZhdWx0IFBBUlJBWVxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuUEFSUkFZID0gW1xuICAgIDB4MjQzZjZhODgsIDB4ODVhMzA4ZDMsIDB4MTMxOThhMmUsIDB4MDM3MDczNDQsIDB4YTQwOTM4MjIsIDB4Mjk5ZjMxZDAsXG4gICAgMHgwODJlZmE5OCwgMHhlYzRlNmM4OSwgMHg0NTI4MjFlNiwgMHgzOGQwMTM3NywgMHhiZTU0NjZjZiwgMHgzNGU5MGM2YyxcbiAgICAweGMwYWMyOWI3LCAweGM5N2M1MGRkLCAweDNmODRkNWI1LCAweGI1NDcwOTE3LCAweDkyMTZkNWQ5LCAweDg5NzlmYjFiXG5dO1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBudW1iZXIgb2Ygcm91bmRzIHRoZSBjaXBoZXIgd2lsbCBnb1xuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuTk4gPSAxNjtcblxuLy8qXG4vLyogVGhpcyBmdW5jdGlvbiBpcyBuZWVkZWQgdG8gZ2V0IHJpZCBvZiBwcm9ibGVtc1xuLy8qIHdpdGggdGhlIGhpZ2gtYml0IGdldHRpbmcgc2V0LiAgSWYgd2UgZG9uJ3QgZG9cbi8vKiB0aGlzLCB0aGVuIHNvbWV0aW1lcyAoIGFhICYgMHgwMEZGRkZGRkZGICkgaXMgbm90XG4vLyogZXF1YWwgdG8gKCBiYiAmIDB4MDBGRkZGRkZGRiApIGV2ZW4gd2hlbiB0aGV5XG4vLyogYWdyZWUgYml0LWZvci1iaXQgZm9yIHRoZSBmaXJzdCAzMiBiaXRzLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX2NsZWFuID0gZnVuY3Rpb24oeHgpIHtcbiAgaWYgKHh4IDwgMCkge1xuICAgIHZhciB5eSA9IHh4ICYgMHg3RkZGRkZGRjtcbiAgICB4eCA9IHl5ICsgMHg4MDAwMDAwMDtcbiAgfVxuICByZXR1cm4geHg7XG59O1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBtaXhpbmcgZnVuY3Rpb24gdGhhdCB1c2VzIHRoZSBzYm94ZXNcbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9GID0gZnVuY3Rpb24oeHgpIHtcbiAgdmFyIGFhO1xuICB2YXIgYmI7XG4gIHZhciBjYztcbiAgdmFyIGRkO1xuICB2YXIgeXk7XG5cbiAgZGQgPSB4eCAmIDB4MDBGRjtcbiAgeHggPj4+PSA4O1xuICBjYyA9IHh4ICYgMHgwMEZGO1xuICB4eCA+Pj49IDg7XG4gIGJiID0geHggJiAweDAwRkY7XG4gIHh4ID4+Pj0gODtcbiAgYWEgPSB4eCAmIDB4MDBGRjtcblxuICB5eSA9IHRoaXMuc2JveGVzWzBdW2FhXSArIHRoaXMuc2JveGVzWzFdW2JiXTtcbiAgeXkgPSB5eSBeIHRoaXMuc2JveGVzWzJdW2NjXTtcbiAgeXkgPSB5eSArIHRoaXMuc2JveGVzWzNdW2RkXTtcblxuICByZXR1cm4geXk7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0XG4vLyogYW5kIGRvZXMgTk4gcm91bmRzIG9mIEJsb3dmaXNoIG9uIHRoZW0uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fZW5jcnlwdF9ibG9jayA9IGZ1bmN0aW9uKHZhbHMpIHtcbiAgdmFyIGRhdGFMID0gdmFsc1swXTtcbiAgdmFyIGRhdGFSID0gdmFsc1sxXTtcblxuICB2YXIgaWk7XG5cbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5OTjsgKytpaSkge1xuICAgIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVtpaV07XG4gICAgZGF0YVIgPSB0aGlzLl9GKGRhdGFMKSBeIGRhdGFSO1xuXG4gICAgdmFyIHRtcCA9IGRhdGFMO1xuICAgIGRhdGFMID0gZGF0YVI7XG4gICAgZGF0YVIgPSB0bXA7XG4gIH1cblxuICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbdGhpcy5OTiArIDBdO1xuICBkYXRhUiA9IGRhdGFSIF4gdGhpcy5wYXJyYXlbdGhpcy5OTiArIDFdO1xuXG4gIHZhbHNbMF0gPSB0aGlzLl9jbGVhbihkYXRhUik7XG4gIHZhbHNbMV0gPSB0aGlzLl9jbGVhbihkYXRhTCk7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhIHZlY3RvciBvZiBudW1iZXJzIGFuZCB0dXJucyB0aGVtXG4vLyogaW50byBsb25nIHdvcmRzIHNvIHRoYXQgdGhleSBjYW4gYmUgcHJvY2Vzc2VkIGJ5IHRoZVxuLy8qIHJlYWwgYWxnb3JpdGhtLlxuLy8qXG4vLyogTWF5YmUgSSBzaG91bGQgbWFrZSB0aGUgcmVhbCBhbGdvcml0aG0gYWJvdmUgdGFrZSBhIHZlY3RvclxuLy8qIGluc3RlYWQuICBUaGF0IHdpbGwgaW52b2x2ZSBtb3JlIGxvb3BpbmcsIGJ1dCBpdCB3b24ndCByZXF1aXJlXG4vLyogdGhlIEYoKSBtZXRob2QgdG8gZGVjb25zdHJ1Y3QgdGhlIHZlY3Rvci5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLmVuY3J5cHRfYmxvY2sgPSBmdW5jdGlvbih2ZWN0b3IpIHtcbiAgdmFyIGlpO1xuICB2YXIgdmFscyA9IFswLCAwXTtcbiAgdmFyIG9mZiA9IHRoaXMuQkxPQ0tTSVpFIC8gMjtcbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5CTE9DS1NJWkUgLyAyOyArK2lpKSB7XG4gICAgdmFsc1swXSA9ICh2YWxzWzBdIDw8IDgpIHwgKHZlY3RvcltpaSArIDBdICYgMHgwMEZGKTtcbiAgICB2YWxzWzFdID0gKHZhbHNbMV0gPDwgOCkgfCAodmVjdG9yW2lpICsgb2ZmXSAmIDB4MDBGRik7XG4gIH1cblxuICB0aGlzLl9lbmNyeXB0X2Jsb2NrKHZhbHMpO1xuXG4gIHZhciByZXQgPSBbXTtcbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5CTE9DS1NJWkUgLyAyOyArK2lpKSB7XG4gICAgcmV0W2lpICsgMF0gPSAodmFsc1swXSA+Pj4gKDI0IC0gOCAqIChpaSkpICYgMHgwMEZGKTtcbiAgICByZXRbaWkgKyBvZmZdID0gKHZhbHNbMV0gPj4+ICgyNCAtIDggKiAoaWkpKSAmIDB4MDBGRik7XG4gICAgLy8gdmFsc1sgMCBdID0gKCB2YWxzWyAwIF0gPj4+IDggKTtcbiAgICAvLyB2YWxzWyAxIF0gPSAoIHZhbHNbIDEgXSA+Pj4gOCApO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGFuIGFycmF5IHdpdGggdHdvIHZhbHVlcywgbGVmdCBhbmQgcmlnaHRcbi8vKiBhbmQgdW5kb2VzIE5OIHJvdW5kcyBvZiBCbG93ZmlzaCBvbiB0aGVtLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX2RlY3J5cHRfYmxvY2sgPSBmdW5jdGlvbih2YWxzKSB7XG4gIHZhciBkYXRhTCA9IHZhbHNbMF07XG4gIHZhciBkYXRhUiA9IHZhbHNbMV07XG5cbiAgdmFyIGlpO1xuXG4gIGZvciAoaWkgPSB0aGlzLk5OICsgMTsgaWkgPiAxOyAtLWlpKSB7XG4gICAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5W2lpXTtcbiAgICBkYXRhUiA9IHRoaXMuX0YoZGF0YUwpIF4gZGF0YVI7XG5cbiAgICB2YXIgdG1wID0gZGF0YUw7XG4gICAgZGF0YUwgPSBkYXRhUjtcbiAgICBkYXRhUiA9IHRtcDtcbiAgfVxuXG4gIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVsxXTtcbiAgZGF0YVIgPSBkYXRhUiBeIHRoaXMucGFycmF5WzBdO1xuXG4gIHZhbHNbMF0gPSB0aGlzLl9jbGVhbihkYXRhUik7XG4gIHZhbHNbMV0gPSB0aGlzLl9jbGVhbihkYXRhTCk7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhIGtleSBhcnJheSBhbmQgaW5pdGlhbGl6ZXMgdGhlXG4vLyogc2JveGVzIGFuZCBwYXJyYXkgZm9yIHRoaXMgZW5jcnlwdGlvbi5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihrZXkpIHtcbiAgdmFyIGlpO1xuICB2YXIgamogPSAwO1xuXG4gIHRoaXMucGFycmF5ID0gW107XG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuTk4gKyAyOyArK2lpKSB7XG4gICAgdmFyIGRhdGEgPSAweDAwMDAwMDAwO1xuICAgIHZhciBraztcbiAgICBmb3IgKGtrID0gMDsga2sgPCA0OyArK2trKSB7XG4gICAgICBkYXRhID0gKGRhdGEgPDwgOCkgfCAoa2V5W2pqXSAmIDB4MDBGRik7XG4gICAgICBpZiAoKytqaiA+PSBrZXkubGVuZ3RoKSB7XG4gICAgICAgIGpqID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5wYXJyYXlbaWldID0gdGhpcy5QQVJSQVlbaWldIF4gZGF0YTtcbiAgfVxuXG4gIHRoaXMuc2JveGVzID0gW107XG4gIGZvciAoaWkgPSAwOyBpaSA8IDQ7ICsraWkpIHtcbiAgICB0aGlzLnNib3hlc1tpaV0gPSBbXTtcbiAgICBmb3IgKGpqID0gMDsgamogPCAyNTY7ICsramopIHtcbiAgICAgIHRoaXMuc2JveGVzW2lpXVtqal0gPSB0aGlzLlNCT1hFU1tpaV1bampdO1xuICAgIH1cbiAgfVxuXG4gIHZhciB2YWxzID0gWzB4MDAwMDAwMDAsIDB4MDAwMDAwMDBdO1xuXG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuTk4gKyAyOyBpaSArPSAyKSB7XG4gICAgdGhpcy5fZW5jcnlwdF9ibG9jayh2YWxzKTtcbiAgICB0aGlzLnBhcnJheVtpaSArIDBdID0gdmFsc1swXTtcbiAgICB0aGlzLnBhcnJheVtpaSArIDFdID0gdmFsc1sxXTtcbiAgfVxuXG4gIGZvciAoaWkgPSAwOyBpaSA8IDQ7ICsraWkpIHtcbiAgICBmb3IgKGpqID0gMDsgamogPCAyNTY7IGpqICs9IDIpIHtcbiAgICAgIHRoaXMuX2VuY3J5cHRfYmxvY2sodmFscyk7XG4gICAgICB0aGlzLnNib3hlc1tpaV1bamogKyAwXSA9IHZhbHNbMF07XG4gICAgICB0aGlzLnNib3hlc1tpaV1bamogKyAxXSA9IHZhbHNbMV07XG4gICAgfVxuICB9XG59O1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuXG5mdW5jdGlvbiBCRmVuY3J5cHQoYmxvY2ssIGtleSkge1xuICB2YXIgYmYgPSBuZXcgQmxvd2Zpc2goKTtcbiAgYmYuaW5pdCh1dGlsLnN0cjJiaW4oa2V5KSk7XG4gIHJldHVybiBiZi5lbmNyeXB0X2Jsb2NrKGJsb2NrKTtcbn1cblxuZnVuY3Rpb24gQkYoa2V5KSB7XG4gIHRoaXMuYmYgPSBuZXcgQmxvd2Zpc2goKTtcbiAgdGhpcy5iZi5pbml0KHV0aWwuc3RyMmJpbihrZXkpKTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgIHJldHVybiB0aGlzLmJmLmVuY3J5cHRfYmxvY2soYmxvY2spO1xuICB9XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBCRjtcbm1vZHVsZS5leHBvcnRzLmtleVNpemUgPSBCRi5wcm90b3R5cGUua2V5U2l6ZSA9IDE2O1xubW9kdWxlLmV4cG9ydHMuYmxvY2tTaXplID0gQkYucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDE2O1xuIiwiLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGVcbi8vIGxpY2Vuc2UgdGhhdCBjYW4gYmUgZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS5cblxuLy8gQ29weXJpZ2h0IDIwMTAgcGphY29ic0B4ZWVrci5jb20gLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuXG4vLyBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcblxuLy8gZml4ZWQvbW9kaWZpZWQgYnkgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuLy8gY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvblxuXG4vLyBjYXN0NS5qcyBpcyBhIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgQ0FTVC0xMjgsIGFzIGRlZmluZWQgaW4gUkZDIDIxNDQuXG4vLyBDQVNULTEyOCBpcyBhIGNvbW1vbiBPcGVuUEdQIGNpcGhlci5cblxuXG4vLyBDQVNUNSBjb25zdHJ1Y3RvclxuXG4vKiogQG1vZHVsZSBjcnlwdG8vY2lwaGVyL2Nhc3Q1ICovXG5cblxuXG5mdW5jdGlvbiBvcGVucGdwX3N5bWVuY19jYXN0NSgpIHtcbiAgdGhpcy5CbG9ja1NpemUgPSA4O1xuICB0aGlzLktleVNpemUgPSAxNjtcblxuICB0aGlzLnNldEtleSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHRoaXMubWFza2luZyA9IG5ldyBBcnJheSgxNik7XG4gICAgdGhpcy5yb3RhdGUgPSBuZXcgQXJyYXkoMTYpO1xuXG4gICAgdGhpcy5yZXNldCgpO1xuXG4gICAgaWYgKGtleS5sZW5ndGggPT0gdGhpcy5LZXlTaXplKSB7XG4gICAgICB0aGlzLmtleVNjaGVkdWxlKGtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ0FTVC0xMjg6IGtleXMgbXVzdCBiZSAxNiBieXRlcycpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICB0aGlzLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB0aGlzLm1hc2tpbmdbaV0gPSAwO1xuICAgICAgdGhpcy5yb3RhdGVbaV0gPSAwO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldEJsb2NrU2l6ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBCbG9ja1NpemU7XG4gIH07XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc3JjKSB7XG4gICAgdmFyIGRzdCA9IG5ldyBBcnJheShzcmMubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSArPSA4KSB7XG4gICAgICB2YXIgbCA9IHNyY1tpXSA8PCAyNCB8IHNyY1tpICsgMV0gPDwgMTYgfCBzcmNbaSArIDJdIDw8IDggfCBzcmNbaSArIDNdO1xuICAgICAgdmFyIHIgPSBzcmNbaSArIDRdIDw8IDI0IHwgc3JjW2kgKyA1XSA8PCAxNiB8IHNyY1tpICsgNl0gPDwgOCB8IHNyY1tpICsgN107XG4gICAgICB2YXIgdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1swXSwgdGhpcy5yb3RhdGVbMF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzFdLCB0aGlzLnJvdGF0ZVsxXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMl0sIHRoaXMucm90YXRlWzJdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1szXSwgdGhpcy5yb3RhdGVbM10pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbNF0sIHRoaXMucm90YXRlWzRdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s1XSwgdGhpcy5yb3RhdGVbNV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzZdLCB0aGlzLnJvdGF0ZVs2XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbN10sIHRoaXMucm90YXRlWzddKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzhdLCB0aGlzLnJvdGF0ZVs4XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbOV0sIHRoaXMucm90YXRlWzldKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxMF0sIHRoaXMucm90YXRlWzEwXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTFdLCB0aGlzLnJvdGF0ZVsxMV0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTJdLCB0aGlzLnJvdGF0ZVsxMl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEzXSwgdGhpcy5yb3RhdGVbMTNdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxNF0sIHRoaXMucm90YXRlWzE0XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTVdLCB0aGlzLnJvdGF0ZVsxNV0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIGRzdFtpXSA9IChyID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDFdID0gKHIgPj4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMl0gPSAociA+Pj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDNdID0gciAmIDI1NTtcbiAgICAgIGRzdFtpICsgNF0gPSAobCA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyA1XSA9IChsID4+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDZdID0gKGwgPj4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyA3XSA9IGwgJiAyNTU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRzdDtcbiAgfTtcblxuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzcmMpIHtcbiAgICB2YXIgZHN0ID0gbmV3IEFycmF5KHNyYy5sZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpICs9IDgpIHtcbiAgICAgIHZhciBsID0gc3JjW2ldIDw8IDI0IHwgc3JjW2kgKyAxXSA8PCAxNiB8IHNyY1tpICsgMl0gPDwgOCB8IHNyY1tpICsgM107XG4gICAgICB2YXIgciA9IHNyY1tpICsgNF0gPDwgMjQgfCBzcmNbaSArIDVdIDw8IDE2IHwgc3JjW2kgKyA2XSA8PCA4IHwgc3JjW2kgKyA3XTtcbiAgICAgIHZhciB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzE1XSwgdGhpcy5yb3RhdGVbMTVdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxNF0sIHRoaXMucm90YXRlWzE0XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTNdLCB0aGlzLnJvdGF0ZVsxM10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzEyXSwgdGhpcy5yb3RhdGVbMTJdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzExXSwgdGhpcy5yb3RhdGVbMTFdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxMF0sIHRoaXMucm90YXRlWzEwXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbOV0sIHRoaXMucm90YXRlWzldKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s4XSwgdGhpcy5yb3RhdGVbOF0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbN10sIHRoaXMucm90YXRlWzddKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s2XSwgdGhpcy5yb3RhdGVbNl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzVdLCB0aGlzLnJvdGF0ZVs1XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbNF0sIHRoaXMucm90YXRlWzRdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzNdLCB0aGlzLnJvdGF0ZVszXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMl0sIHRoaXMucm90YXRlWzJdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxXSwgdGhpcy5yb3RhdGVbMV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzBdLCB0aGlzLnJvdGF0ZVswXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgZHN0W2ldID0gKHIgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMV0gPSAociA+Pj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyAyXSA9IChyID4+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgM10gPSByICYgMjU1O1xuICAgICAgZHN0W2kgKyA0XSA9IChsID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDVdID0gKGwgPj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyA2XSA9IChsID4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyA3XSA9IGwgJiAyNTU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRzdDtcbiAgfTtcbiAgdmFyIHNjaGVkdWxlQSA9IG5ldyBBcnJheSg0KTtcblxuICBzY2hlZHVsZUFbMF0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVswXVswXSA9IG5ldyBBcnJheSg0LCAwLCAweGQsIDB4ZiwgMHhjLCAweGUsIDB4OCk7XG4gIHNjaGVkdWxlQVswXVsxXSA9IG5ldyBBcnJheSg1LCAyLCAxNiArIDAsIDE2ICsgMiwgMTYgKyAxLCAxNiArIDMsIDB4YSk7XG4gIHNjaGVkdWxlQVswXVsyXSA9IG5ldyBBcnJheSg2LCAzLCAxNiArIDcsIDE2ICsgNiwgMTYgKyA1LCAxNiArIDQsIDkpO1xuICBzY2hlZHVsZUFbMF1bM10gPSBuZXcgQXJyYXkoNywgMSwgMTYgKyAweGEsIDE2ICsgOSwgMTYgKyAweGIsIDE2ICsgOCwgMHhiKTtcblxuICBzY2hlZHVsZUFbMV0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVsxXVswXSA9IG5ldyBBcnJheSgwLCA2LCAxNiArIDUsIDE2ICsgNywgMTYgKyA0LCAxNiArIDYsIDE2ICsgMCk7XG4gIHNjaGVkdWxlQVsxXVsxXSA9IG5ldyBBcnJheSgxLCA0LCAwLCAyLCAxLCAzLCAxNiArIDIpO1xuICBzY2hlZHVsZUFbMV1bMl0gPSBuZXcgQXJyYXkoMiwgNSwgNywgNiwgNSwgNCwgMTYgKyAxKTtcbiAgc2NoZWR1bGVBWzFdWzNdID0gbmV3IEFycmF5KDMsIDcsIDB4YSwgOSwgMHhiLCA4LCAxNiArIDMpO1xuXG4gIHNjaGVkdWxlQVsyXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzJdWzBdID0gbmV3IEFycmF5KDQsIDAsIDB4ZCwgMHhmLCAweGMsIDB4ZSwgOCk7XG4gIHNjaGVkdWxlQVsyXVsxXSA9IG5ldyBBcnJheSg1LCAyLCAxNiArIDAsIDE2ICsgMiwgMTYgKyAxLCAxNiArIDMsIDB4YSk7XG4gIHNjaGVkdWxlQVsyXVsyXSA9IG5ldyBBcnJheSg2LCAzLCAxNiArIDcsIDE2ICsgNiwgMTYgKyA1LCAxNiArIDQsIDkpO1xuICBzY2hlZHVsZUFbMl1bM10gPSBuZXcgQXJyYXkoNywgMSwgMTYgKyAweGEsIDE2ICsgOSwgMTYgKyAweGIsIDE2ICsgOCwgMHhiKTtcblxuXG4gIHNjaGVkdWxlQVszXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzNdWzBdID0gbmV3IEFycmF5KDAsIDYsIDE2ICsgNSwgMTYgKyA3LCAxNiArIDQsIDE2ICsgNiwgMTYgKyAwKTtcbiAgc2NoZWR1bGVBWzNdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7XG4gIHNjaGVkdWxlQVszXVsyXSA9IG5ldyBBcnJheSgyLCA1LCA3LCA2LCA1LCA0LCAxNiArIDEpO1xuICBzY2hlZHVsZUFbM11bM10gPSBuZXcgQXJyYXkoMywgNywgMHhhLCA5LCAweGIsIDgsIDE2ICsgMyk7XG5cbiAgdmFyIHNjaGVkdWxlQiA9IG5ldyBBcnJheSg0KTtcblxuICBzY2hlZHVsZUJbMF0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQlswXVswXSA9IG5ldyBBcnJheSgxNiArIDgsIDE2ICsgOSwgMTYgKyA3LCAxNiArIDYsIDE2ICsgMik7XG4gIHNjaGVkdWxlQlswXVsxXSA9IG5ldyBBcnJheSgxNiArIDB4YSwgMTYgKyAweGIsIDE2ICsgNSwgMTYgKyA0LCAxNiArIDYpO1xuICBzY2hlZHVsZUJbMF1bMl0gPSBuZXcgQXJyYXkoMTYgKyAweGMsIDE2ICsgMHhkLCAxNiArIDMsIDE2ICsgMiwgMTYgKyA5KTtcbiAgc2NoZWR1bGVCWzBdWzNdID0gbmV3IEFycmF5KDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhjKTtcblxuICBzY2hlZHVsZUJbMV0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQlsxXVswXSA9IG5ldyBBcnJheSgzLCAyLCAweGMsIDB4ZCwgOCk7XG4gIHNjaGVkdWxlQlsxXVsxXSA9IG5ldyBBcnJheSgxLCAwLCAweGUsIDB4ZiwgMHhkKTtcbiAgc2NoZWR1bGVCWzFdWzJdID0gbmV3IEFycmF5KDcsIDYsIDgsIDksIDMpO1xuICBzY2hlZHVsZUJbMV1bM10gPSBuZXcgQXJyYXkoNSwgNCwgMHhhLCAweGIsIDcpO1xuXG5cbiAgc2NoZWR1bGVCWzJdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbMl1bMF0gPSBuZXcgQXJyYXkoMTYgKyAzLCAxNiArIDIsIDE2ICsgMHhjLCAxNiArIDB4ZCwgMTYgKyA5KTtcbiAgc2NoZWR1bGVCWzJdWzFdID0gbmV3IEFycmF5KDE2ICsgMSwgMTYgKyAwLCAxNiArIDB4ZSwgMTYgKyAweGYsIDE2ICsgMHhjKTtcbiAgc2NoZWR1bGVCWzJdWzJdID0gbmV3IEFycmF5KDE2ICsgNywgMTYgKyA2LCAxNiArIDgsIDE2ICsgOSwgMTYgKyAyKTtcbiAgc2NoZWR1bGVCWzJdWzNdID0gbmV3IEFycmF5KDE2ICsgNSwgMTYgKyA0LCAxNiArIDB4YSwgMTYgKyAweGIsIDE2ICsgNik7XG5cblxuICBzY2hlZHVsZUJbM10gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQlszXVswXSA9IG5ldyBBcnJheSg4LCA5LCA3LCA2LCAzKTtcbiAgc2NoZWR1bGVCWzNdWzFdID0gbmV3IEFycmF5KDB4YSwgMHhiLCA1LCA0LCA3KTtcbiAgc2NoZWR1bGVCWzNdWzJdID0gbmV3IEFycmF5KDB4YywgMHhkLCAzLCAyLCA4KTtcbiAgc2NoZWR1bGVCWzNdWzNdID0gbmV3IEFycmF5KDB4ZSwgMHhmLCAxLCAwLCAweGQpO1xuXG4gIC8vIGNoYW5nZWQgJ2luJyB0byAnaW5uJyAoaW4gamF2YXNjcmlwdCAnaW4nIGlzIGEgcmVzZXJ2ZWQgd29yZClcbiAgdGhpcy5rZXlTY2hlZHVsZSA9IGZ1bmN0aW9uKGlubikge1xuICAgIHZhciB0ID0gbmV3IEFycmF5KDgpO1xuICAgIHZhciBrID0gbmV3IEFycmF5KDMyKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICB2YXIgaiA9IGkgKiA0O1xuICAgICAgdFtpXSA9IGlubltqXSA8PCAyNCB8IGlubltqICsgMV0gPDwgMTYgfCBpbm5baiArIDJdIDw8IDggfCBpbm5baiArIDNdO1xuICAgIH1cblxuICAgIHZhciB4ID0gWzYsIDcsIDQsIDVdO1xuICAgIHZhciBraSA9IDA7XG5cbiAgICBmb3IgKHZhciBoYWxmID0gMDsgaGFsZiA8IDI7IGhhbGYrKykge1xuICAgICAgZm9yICh2YXIgcm91bmQgPSAwOyByb3VuZCA8IDQ7IHJvdW5kKyspIHtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICB2YXIgYSA9IHNjaGVkdWxlQVtyb3VuZF1bal07XG4gICAgICAgICAgdmFyIHcgPSB0W2FbMV1dO1xuXG4gICAgICAgICAgdyBePSBzQm94WzRdWyh0W2FbMl0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGFbMl0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzVdWyh0W2FbM10gPj4+IDJdID4+PiAoMjQgLSA4ICogKGFbM10gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzZdWyh0W2FbNF0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGFbNF0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzddWyh0W2FbNV0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGFbNV0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94W3hbal1dWyh0W2FbNl0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGFbNl0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdFthWzBdXSA9IHc7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICAgIHZhciBiID0gc2NoZWR1bGVCW3JvdW5kXVtqXTtcbiAgICAgICAgICB2YXIgdyA9IHNCb3hbNF1bKHRbYlswXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlswXSAmIDMpKSkgJiAweGZmXTtcblxuICAgICAgICAgIHcgXj0gc0JveFs1XVsodFtiWzFdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzFdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs2XVsodFtiWzJdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzJdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs3XVsodFtiWzNdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzNdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs0ICsgal1bKHRbYls0XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYls0XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICBrW2tpXSA9IHc7XG4gICAgICAgICAga2krKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgdGhpcy5tYXNraW5nW2ldID0ga1tpXTtcbiAgICAgIHRoaXMucm90YXRlW2ldID0ga1sxNiArIGldICYgMHgxZjtcbiAgICB9XG4gIH07XG5cbiAgLy8gVGhlc2UgYXJlIHRoZSB0aHJlZSAnZicgZnVuY3Rpb25zLiBTZWUgUkZDIDIxNDQsIHNlY3Rpb24gMi4yLlxuXG4gIGZ1bmN0aW9uIGYxKGQsIG0sIHIpIHtcbiAgICB2YXIgdCA9IG0gKyBkO1xuICAgIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpO1xuICAgIHJldHVybiAoKHNCb3hbMF1bSSA+Pj4gMjRdIF4gc0JveFsxXVsoSSA+Pj4gMTYpICYgMjU1XSkgLSBzQm94WzJdWyhJID4+PiA4KSAmIDI1NV0pICsgc0JveFszXVtJICYgMjU1XTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGYyKGQsIG0sIHIpIHtcbiAgICB2YXIgdCA9IG0gXiBkO1xuICAgIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpO1xuICAgIHJldHVybiAoKHNCb3hbMF1bSSA+Pj4gMjRdIC0gc0JveFsxXVsoSSA+Pj4gMTYpICYgMjU1XSkgKyBzQm94WzJdWyhJID4+PiA4KSAmIDI1NV0pIF4gc0JveFszXVtJICYgMjU1XTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGYzKGQsIG0sIHIpIHtcbiAgICB2YXIgdCA9IG0gLSBkO1xuICAgIHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpO1xuICAgIHJldHVybiAoKHNCb3hbMF1bSSA+Pj4gMjRdICsgc0JveFsxXVsoSSA+Pj4gMTYpICYgMjU1XSkgXiBzQm94WzJdWyhJID4+PiA4KSAmIDI1NV0pIC0gc0JveFszXVtJICYgMjU1XTtcbiAgfVxuXG4gIHZhciBzQm94ID0gbmV3IEFycmF5KDgpO1xuICBzQm94WzBdID0gbmV3IEFycmF5KFxuICAgIDB4MzBmYjQwZDQsIDB4OWZhMGZmMGIsIDB4NmJlY2NkMmYsIDB4M2YyNThjN2EsIDB4MWUyMTNmMmYsIDB4OWMwMDRkZDMsIDB4NjAwM2U1NDAsIDB4Y2Y5ZmM5NDksXG4gICAgMHhiZmQ0YWYyNywgMHg4OGJiYmRiNSwgMHhlMjAzNDA5MCwgMHg5OGQwOTY3NSwgMHg2ZTYzYTBlMCwgMHgxNWMzNjFkMiwgMHhjMmU3NjYxZCwgMHgyMmQ0ZmY4ZSxcbiAgICAweDI4NjgzYjZmLCAweGMwN2ZkMDU5LCAweGZmMjM3OWM4LCAweDc3NWY1MGUyLCAweDQzYzM0MGQzLCAweGRmMmY4NjU2LCAweDg4N2NhNDFhLCAweGEyZDJiZDJkLFxuICAgIDB4YTFjOWUwZDYsIDB4MzQ2YzQ4MTksIDB4NjFiNzZkODcsIDB4MjI1NDBmMmYsIDB4MmFiZTMyZTEsIDB4YWE1NDE2NmIsIDB4MjI1NjhlM2EsIDB4YTJkMzQxZDAsXG4gICAgMHg2NmRiNDBjOCwgMHhhNzg0MzkyZiwgMHgwMDRkZmYyZiwgMHgyZGI5ZDJkZSwgMHg5Nzk0M2ZhYywgMHg0YTk3YzFkOCwgMHg1Mjc2NDRiNywgMHhiNWY0MzdhNyxcbiAgICAweGI4MmNiYWVmLCAweGQ3NTFkMTU5LCAweDZmZjdmMGVkLCAweDVhMDk3YTFmLCAweDgyN2I2OGQwLCAweDkwZWNmNTJlLCAweDIyYjBjMDU0LCAweGJjOGU1OTM1LFxuICAgIDB4NGI2ZDJmN2YsIDB4NTBiYjY0YTIsIDB4ZDI2NjQ5MTAsIDB4YmVlNTgxMmQsIDB4YjczMzIyOTAsIDB4ZTkzYjE1OWYsIDB4YjQ4ZWU0MTEsIDB4NGJmZjM0NWQsXG4gICAgMHhmZDQ1YzI0MCwgMHhhZDMxOTczZiwgMHhjNGY2ZDAyZSwgMHg1NWZjODE2NSwgMHhkNWIxY2FhZCwgMHhhMWFjMmRhZSwgMHhhMmQ0Yjc2ZCwgMHhjMTliMGM1MCxcbiAgICAweDg4MjI0MGYyLCAweDBjNmU0ZjM4LCAweGE0ZTRiZmQ3LCAweDRmNWJhMjcyLCAweDU2NGMxZDJmLCAweGM1OWM1MzE5LCAweGI5NDllMzU0LCAweGIwNDY2OWZlLFxuICAgIDB4YjFiNmFiOGEsIDB4YzcxMzU4ZGQsIDB4NjM4NWM1NDUsIDB4MTEwZjkzNWQsIDB4NTc1MzhhZDUsIDB4NmEzOTA0OTMsIDB4ZTYzZDM3ZTAsIDB4MmE1NGY2YjMsXG4gICAgMHgzYTc4N2Q1ZiwgMHg2Mjc2YTBiNSwgMHgxOWE2ZmNkZiwgMHg3YTQyMjA2YSwgMHgyOWY5ZDRkNSwgMHhmNjFiMTg5MSwgMHhiYjcyMjc1ZSwgMHhhYTUwODE2NyxcbiAgICAweDM4OTAxMDkxLCAweGM2YjUwNWViLCAweDg0YzdjYjhjLCAweDJhZDc1YTBmLCAweDg3NGExNDI3LCAweGEyZDE5MzZiLCAweDJhZDI4NmFmLCAweGFhNTZkMjkxLFxuICAgIDB4ZDc4OTQzNjAsIDB4NDI1Yzc1MGQsIDB4OTNiMzllMjYsIDB4MTg3MTg0YzksIDB4NmMwMGIzMmQsIDB4NzNlMmJiMTQsIDB4YTBiZWJjM2MsIDB4NTQ2MjM3NzksXG4gICAgMHg2NDQ1OWVhYiwgMHgzZjMyOGI4MiwgMHg3NzE4Y2Y4MiwgMHg1OWEyY2VhNiwgMHgwNGVlMDAyZSwgMHg4OWZlNzhlNiwgMHgzZmFiMDk1MCwgMHgzMjVmZjZjMixcbiAgICAweDgxMzgzZjA1LCAweDY5NjNjNWM4LCAweDc2Y2I1YWQ2LCAweGQ0OTk3NGM5LCAweGNhMTgwZGNmLCAweDM4MDc4MmQ1LCAweGM3ZmE1Y2Y2LCAweDhhYzMxNTExLFxuICAgIDB4MzVlNzllMTMsIDB4NDdkYTkxZDAsIDB4ZjQwZjkwODYsIDB4YTdlMjQxOWUsIDB4MzEzNjYyNDEsIDB4MDUxZWY0OTUsIDB4YWE1NzNiMDQsIDB4NGE4MDVkOGQsXG4gICAgMHg1NDgzMDBkMCwgMHgwMDMyMmEzYywgMHhiZjY0Y2RkZiwgMHhiYTU3YTY4ZSwgMHg3NWM2MzcyYiwgMHg1MGFmZDM0MSwgMHhhN2MxMzI3NSwgMHg5MTVhMGJmNSxcbiAgICAweDZiNTRiZmFiLCAweDJiMGIxNDI2LCAweGFiNGNjOWQ3LCAweDQ0OWNjZDgyLCAweGY3ZmJmMjY1LCAweGFiODVjNWYzLCAweDFiNTVkYjk0LCAweGFhZDRlMzI0LFxuICAgIDB4Y2ZhNGJkM2YsIDB4MmRlYWEzZTIsIDB4OWUyMDRkMDIsIDB4YzhiZDI1YWMsIDB4ZWFkZjU1YjMsIDB4ZDViZDllOTgsIDB4ZTMxMjMxYjIsIDB4MmFkNWFkNmMsXG4gICAgMHg5NTQzMjlkZSwgMHhhZGJlNDUyOCwgMHhkODcxMGY2OSwgMHhhYTUxYzkwZiwgMHhhYTc4NmJmNiwgMHgyMjUxM2YxZSwgMHhhYTUxYTc5YiwgMHgyYWQzNDRjYyxcbiAgICAweDdiNWE0MWYwLCAweGQzN2NmYmFkLCAweDFiMDY5NTA1LCAweDQxZWNlNDkxLCAweGI0YzMzMmU2LCAweDAzMjI2OGQ0LCAweGM5NjAwYWNjLCAweGNlMzg3ZTZkLFxuICAgIDB4YmY2YmIxNmMsIDB4NmE3MGZiNzgsIDB4MGQwM2Q5YzksIDB4ZDRkZjM5ZGUsIDB4ZTAxMDYzZGEsIDB4NDczNmY0NjQsIDB4NWFkMzI4ZDgsIDB4YjM0N2NjOTYsXG4gICAgMHg3NWJiMGZjMywgMHg5ODUxMWJmYiwgMHg0ZmZiY2MzNSwgMHhiNThiY2Y2YSwgMHhlMTFmMGFiYywgMHhiZmM1ZmU0YSwgMHhhNzBhZWMxMCwgMHhhYzM5NTcwYSxcbiAgICAweDNmMDQ0NDJmLCAweDYxODhiMTUzLCAweGUwMzk3YTJlLCAweDU3MjdjYjc5LCAweDljZWI0MThmLCAweDFjYWNkNjhkLCAweDJhZDM3Yzk2LCAweDAxNzVjYjlkLFxuICAgIDB4YzY5ZGZmMDksIDB4Yzc1YjY1ZjAsIDB4ZDlkYjQwZDgsIDB4ZWMwZTc3NzksIDB4NDc0NGVhZDQsIDB4YjExYzMyNzQsIDB4ZGQyNGNiOWUsIDB4N2UxYzU0YmQsXG4gICAgMHhmMDExNDRmOSwgMHhkMjI0MGViMSwgMHg5Njc1YjNmZCwgMHhhM2FjMzc1NSwgMHhkNDdjMjdhZiwgMHg1MWM4NWY0ZCwgMHg1NjkwNzU5NiwgMHhhNWJiMTVlNixcbiAgICAweDU4MDMwNGYwLCAweGNhMDQyY2YxLCAweDAxMWEzN2VhLCAweDhkYmZhYWRiLCAweDM1YmEzZTRhLCAweDM1MjZmZmEwLCAweGMzN2I0ZDA5LCAweGJjMzA2ZWQ5LFxuICAgIDB4OThhNTI2NjYsIDB4NTY0OGY3MjUsIDB4ZmY1ZTU2OWQsIDB4MGNlZDYzZDAsIDB4N2M2M2IyY2YsIDB4NzAwYjQ1ZTEsIDB4ZDVlYTUwZjEsIDB4ODVhOTI4NzIsXG4gICAgMHhhZjFmYmRhNywgMHhkNDIzNDg3MCwgMHhhNzg3MGJmMywgMHgyZDNiNGQ3OSwgMHg0MmUwNDE5OCwgMHgwY2QwZWRlNywgMHgyNjQ3MGRiOCwgMHhmODgxODE0YyxcbiAgICAweDQ3NGQ2YWQ3LCAweDdjMGM1ZTVjLCAweGQxMjMxOTU5LCAweDM4MWI3Mjk4LCAweGY1ZDJmNGRiLCAweGFiODM4NjUzLCAweDZlMmYxZTIzLCAweDgzNzE5YzllLFxuICAgIDB4YmQ5MWUwNDYsIDB4OWE1NjQ1NmUsIDB4ZGMzOTIwMGMsIDB4MjBjOGM1NzEsIDB4OTYyYmRhMWMsIDB4ZTFlNjk2ZmYsIDB4YjE0MWFiMDgsIDB4N2NjYTg5YjksXG4gICAgMHgxYTY5ZTc4MywgMHgwMmNjNDg0MywgMHhhMmY3YzU3OSwgMHg0MjllZjQ3ZCwgMHg0MjdiMTY5YywgMHg1YWM5ZjA0OSwgMHhkZDhmMGYwMCwgMHg1YzgxNjViZik7XG5cbiAgc0JveFsxXSA9IG5ldyBBcnJheShcbiAgICAweDFmMjAxMDk0LCAweGVmMGJhNzViLCAweDY5ZTNjZjdlLCAweDM5M2Y0MzgwLCAweGZlNjFjZjdhLCAweGVlYzUyMDdhLCAweDU1ODg5Yzk0LCAweDcyZmMwNjUxLFxuICAgIDB4YWRhN2VmNzksIDB4NGUxZDcyMzUsIDB4ZDU1YTYzY2UsIDB4ZGUwNDM2YmEsIDB4OTljNDMwZWYsIDB4NWYwYzA3OTQsIDB4MThkY2RiN2QsIDB4YTFkNmVmZjMsXG4gICAgMHhhMGI1MmY3YiwgMHg1OWU4MzYwNSwgMHhlZTE1YjA5NCwgMHhlOWZmZDkwOSwgMHhkYzQ0MDA4NiwgMHhlZjk0NDQ1OSwgMHhiYTgzY2NiMywgMHhlMGMzY2RmYixcbiAgICAweGQxZGE0MTgxLCAweDNiMDkyYWIxLCAweGY5OTdmMWMxLCAweGE1ZTZjZjdiLCAweDAxNDIwZGRiLCAweGU0ZTdlZjViLCAweDI1YTFmZjQxLCAweGUxODBmODA2LFxuICAgIDB4MWZjNDEwODAsIDB4MTc5YmVlN2EsIDB4ZDM3YWM2YTksIDB4ZmU1ODMwYTQsIDB4OThkZThiN2YsIDB4NzdlODNmNGUsIDB4Nzk5MjkyNjksIDB4MjRmYTlmN2IsXG4gICAgMHhlMTEzYzg1YiwgMHhhY2M0MDA4MywgMHhkNzUwMzUyNSwgMHhmN2VhNjE1ZiwgMHg2MjE0MzE1NCwgMHgwZDU1NGI2MywgMHg1ZDY4MTEyMSwgMHhjODY2YzM1OSxcbiAgICAweDNkNjNjZjczLCAweGNlZTIzNGMwLCAweGQ0ZDg3ZTg3LCAweDVjNjcyYjIxLCAweDA3MWY2MTgxLCAweDM5Zjc2MjdmLCAweDM2MWUzMDg0LCAweGU0ZWI1NzNiLFxuICAgIDB4NjAyZjY0YTQsIDB4ZDYzYWNkOWMsIDB4MWJiYzQ2MzUsIDB4OWU4MTAzMmQsIDB4MjcwMWY1MGMsIDB4OTk4NDdhYjQsIDB4YTBlM2RmNzksIDB4YmE2Y2YzOGMsXG4gICAgMHgxMDg0MzA5NCwgMHgyNTM3YTk1ZSwgMHhmNDZmNmZmZSwgMHhhMWZmM2IxZiwgMHgyMDhjZmI2YSwgMHg4ZjQ1OGM3NCwgMHhkOWUwYTIyNywgMHg0ZWM3M2EzNCxcbiAgICAweGZjODg0ZjY5LCAweDNlNGRlOGRmLCAweGVmMGUwMDg4LCAweDM1NTk2NDhkLCAweDhhNDUzODhjLCAweDFkODA0MzY2LCAweDcyMWQ5YmZkLCAweGE1ODY4NGJiLFxuICAgIDB4ZTgyNTYzMzMsIDB4ODQ0ZTgyMTIsIDB4MTI4ZDgwOTgsIDB4ZmVkMzNmYjQsIDB4Y2UyODBhZTEsIDB4MjdlMTliYTUsIDB4ZDVhNmMyNTIsIDB4ZTQ5NzU0YmQsXG4gICAgMHhjNWQ2NTVkZCwgMHhlYjY2NzA2NCwgMHg3Nzg0MGI0ZCwgMHhhMWI2YTgwMSwgMHg4NGRiMjZhOSwgMHhlMGI1NjcxNCwgMHgyMWYwNDNiNywgMHhlNWQwNTg2MCxcbiAgICAweDU0ZjAzMDg0LCAweDA2NmZmNDcyLCAweGEzMWFhMTUzLCAweGRhZGM0NzU1LCAweGI1NjI1ZGJmLCAweDY4NTYxYmU2LCAweDgzY2E2Yjk0LCAweDJkNmVkMjNiLFxuICAgIDB4ZWNjZjAxZGIsIDB4YTZkM2QwYmEsIDB4YjY4MDNkNWMsIDB4YWY3N2E3MDksIDB4MzNiNGEzNGMsIDB4Mzk3YmM4ZDYsIDB4NWVlMjJiOTUsIDB4NWYwZTUzMDQsXG4gICAgMHg4MWVkNmY2MSwgMHgyMGU3NDM2NCwgMHhiNDVlMTM3OCwgMHhkZTE4NjM5YiwgMHg4ODFjYTEyMiwgMHhiOTY3MjZkMSwgMHg4MDQ5YTdlOCwgMHgyMmI3ZGE3YixcbiAgICAweDVlNTUyZDI1LCAweDUyNzJkMjM3LCAweDc5ZDI5NTFjLCAweGM2MGQ4OTRjLCAweDQ4OGNiNDAyLCAweDFiYTRmZTViLCAweGE0YjA5ZjZiLCAweDFjYTgxNWNmLFxuICAgIDB4YTIwYzMwMDUsIDB4ODg3MWRmNjMsIDB4YjlkZTJmY2IsIDB4MGNjNmM5ZTksIDB4MGJlZWZmNTMsIDB4ZTMyMTQ1MTcsIDB4YjQ1NDI4MzUsIDB4OWY2MzI5M2MsXG4gICAgMHhlZTQxZTcyOSwgMHg2ZTFkMmQ3YywgMHg1MDA0NTI4NiwgMHgxZTY2ODVmMywgMHhmMzM0MDFjNiwgMHgzMGEyMmM5NSwgMHgzMWE3MDg1MCwgMHg2MDkzMGYxMyxcbiAgICAweDczZjk4NDE3LCAweGExMjY5ODU5LCAweGVjNjQ1YzQ0LCAweDUyYzg3N2E5LCAweGNkZmYzM2E2LCAweGEwMmIxNzQxLCAweDdjYmFkOWEyLCAweDIxODAwMzZmLFxuICAgIDB4NTBkOTljMDgsIDB4Y2IzZjQ4NjEsIDB4YzI2YmQ3NjUsIDB4NjRhM2Y2YWIsIDB4ODAzNDI2NzYsIDB4MjVhNzVlN2IsIDB4ZTRlNmQxZmMsIDB4MjBjNzEwZTYsXG4gICAgMHhjZGYwYjY4MCwgMHgxNzg0NGQzYiwgMHgzMWVlZjg0ZCwgMHg3ZTA4MjRlNCwgMHgyY2NiNDllYiwgMHg4NDZhM2JhZSwgMHg4ZmY3Nzg4OCwgMHhlZTVkNjBmNixcbiAgICAweDdhZjc1NjczLCAweDJmZGQ1Y2RiLCAweGExMTYzMWMxLCAweDMwZjY2ZjQzLCAweGIzZmFlYzU0LCAweDE1N2ZkN2ZhLCAweGVmODU3OWNjLCAweGQxNTJkZTU4LFxuICAgIDB4ZGIyZmZkNWUsIDB4OGYzMmNlMTksIDB4MzA2YWY5N2EsIDB4MDJmMDNlZjgsIDB4OTkzMTlhZDUsIDB4YzI0MmZhMGYsIDB4YTdlM2ViYjAsIDB4YzY4ZTQ5MDYsXG4gICAgMHhiOGRhMjMwYywgMHg4MDgyMzAyOCwgMHhkY2RlZjNjOCwgMHhkMzVmYjE3MSwgMHgwODhhMWJjOCwgMHhiZWMwYzU2MCwgMHg2MWEzYzllOCwgMHhiY2E4ZjU0ZCxcbiAgICAweGM3MmZlZmZhLCAweDIyODIyZTk5LCAweDgyYzU3MGI0LCAweGQ4ZDk0ZTg5LCAweDhiMWMzNGJjLCAweDMwMWUxNmU2LCAweDI3M2JlOTc5LCAweGIwZmZlYWE2LFxuICAgIDB4NjFkOWI4YzYsIDB4MDBiMjQ4NjksIDB4YjdmZmNlM2YsIDB4MDhkYzI4M2IsIDB4NDNkYWY2NWEsIDB4ZjdlMTk3OTgsIDB4NzYxOWI3MmYsIDB4OGYxYzliYTQsXG4gICAgMHhkYzg2MzdhMCwgMHgxNmE3ZDNiMSwgMHg5ZmMzOTNiNywgMHhhNzEzNmVlYiwgMHhjNmJjYzYzZSwgMHgxYTUxMzc0MiwgMHhlZjY4MjhiYywgMHg1MjAzNjVkNixcbiAgICAweDJkNmE3N2FiLCAweDM1MjdlZDRiLCAweDgyMWZkMjE2LCAweDA5NWM2ZTJlLCAweGRiOTJmMmZiLCAweDVlZWEyOWNiLCAweDE0NTg5MmY1LCAweDkxNTg0ZjdmLFxuICAgIDB4NTQ4MzY5N2IsIDB4MjY2N2E4Y2MsIDB4ODUxOTYwNDgsIDB4OGM0YmFjZWEsIDB4ODMzODYwZDQsIDB4MGQyM2UwZjksIDB4NmMzODdlOGEsIDB4MGFlNmQyNDksXG4gICAgMHhiMjg0NjAwYywgMHhkODM1NzMxZCwgMHhkY2IxYzY0NywgMHhhYzRjNTZlYSwgMHgzZWJkODFiMywgMHgyMzBlYWJiMCwgMHg2NDM4YmM4NywgMHhmMGI1YjFmYSxcbiAgICAweDhmNWVhMmIzLCAweGZjMTg0NjQyLCAweDBhMDM2YjdhLCAweDRmYjA4OWJkLCAweDY0OWRhNTg5LCAweGEzNDU0MTVlLCAweDVjMDM4MzIzLCAweDNlNWQzYmI5LFxuICAgIDB4NDNkNzk1NzIsIDB4N2U2ZGQwN2MsIDB4MDZkZmRmMWUsIDB4NmM2Y2M0ZWYsIDB4NzE2MGE1MzksIDB4NzNiZmJlNzAsIDB4ODM4Nzc2MDUsIDB4NDUyM2VjZjEpO1xuXG4gIHNCb3hbMl0gPSBuZXcgQXJyYXkoXG4gICAgMHg4ZGVmYzI0MCwgMHgyNWZhNWQ5ZiwgMHhlYjkwM2RiZiwgMHhlODEwYzkwNywgMHg0NzYwN2ZmZiwgMHgzNjlmZTQ0YiwgMHg4YzFmYzY0NCwgMHhhZWNlY2E5MCxcbiAgICAweGJlYjFmOWJmLCAweGVlZmJjYWVhLCAweGU4Y2YxOTUwLCAweDUxZGYwN2FlLCAweDkyMGU4ODA2LCAweGYwYWQwNTQ4LCAweGUxM2M4ZDgzLCAweDkyNzAxMGQ1LFxuICAgIDB4MTExMDdkOWYsIDB4MDc2NDdkYjksIDB4YjJlM2U0ZDQsIDB4M2Q0ZjI4NWUsIDB4YjlhZmE4MjAsIDB4ZmFkZTgyZTAsIDB4YTA2NzI2OGIsIDB4ODI3Mjc5MmUsXG4gICAgMHg1NTNmYjJjMCwgMHg0ODlhZTIyYiwgMHhkNGVmOTc5NCwgMHgxMjVlM2ZiYywgMHgyMWZmZmNlZSwgMHg4MjViMWJmZCwgMHg5MjU1YzVlZCwgMHgxMjU3YTI0MCxcbiAgICAweDRlMWE4MzAyLCAweGJhZTA3ZmZmLCAweDUyODI0NmU3LCAweDhlNTcxNDBlLCAweDMzNzNmN2JmLCAweDhjOWY4MTg4LCAweGE2ZmM0ZWU4LCAweGM5ODJiNWE1LFxuICAgIDB4YThjMDFkYjcsIDB4NTc5ZmMyNjQsIDB4NjcwOTRmMzEsIDB4ZjJiZDNmNWYsIDB4NDBmZmY3YzEsIDB4MWZiNzhkZmMsIDB4OGU2YmQyYzEsIDB4NDM3YmU1OWIsXG4gICAgMHg5OWIwM2RiZiwgMHhiNWRiYzY0YiwgMHg2MzhkYzBlNiwgMHg1NTgxOWQ5OSwgMHhhMTk3YzgxYywgMHg0YTAxMmQ2ZSwgMHhjNTg4NGEyOCwgMHhjY2MzNmY3MSxcbiAgICAweGI4NDNjMjEzLCAweDZjMDc0M2YxLCAweDgzMDk4OTNjLCAweDBmZWRkZDVmLCAweDJmN2ZlODUwLCAweGQ3YzA3ZjdlLCAweDAyNTA3ZmJmLCAweDVhZmI5YTA0LFxuICAgIDB4YTc0N2QyZDAsIDB4MTY1MTE5MmUsIDB4YWY3MGJmM2UsIDB4NThjMzEzODAsIDB4NWY5ODMwMmUsIDB4NzI3Y2MzYzQsIDB4MGEwZmI0MDIsIDB4MGY3ZmVmODIsXG4gICAgMHg4Yzk2ZmRhZCwgMHg1ZDJjMmFhZSwgMHg4ZWU5OWE0OSwgMHg1MGRhODhiOCwgMHg4NDI3ZjRhMCwgMHgxZWFjNTc5MCwgMHg3OTZmYjQ0OSwgMHg4MjUyZGMxNSxcbiAgICAweGVmYmQ3ZDliLCAweGE2NzI1OTdkLCAweGFkYTg0MGQ4LCAweDQ1ZjU0NTA0LCAweGZhNWQ3NDAzLCAweGU4M2VjMzA1LCAweDRmOTE3NTFhLCAweDkyNTY2OWMyLFxuICAgIDB4MjNlZmU5NDEsIDB4YTkwM2YxMmUsIDB4NjAyNzBkZjIsIDB4MDI3NmU0YjYsIDB4OTRmZDY1NzQsIDB4OTI3OTg1YjIsIDB4ODI3NmRiY2IsIDB4MDI3NzgxNzYsXG4gICAgMHhmOGFmOTE4ZCwgMHg0ZTQ4Zjc5ZSwgMHg4ZjYxNmRkZiwgMHhlMjlkODQwZSwgMHg4NDJmN2Q4MywgMHgzNDBjZTVjOCwgMHg5NmJiYjY4MiwgMHg5M2I0YjE0OCxcbiAgICAweGVmMzAzY2FiLCAweDk4NGZhZjI4LCAweDc3OWZhZjliLCAweDkyZGM1NjBkLCAweDIyNGQxZTIwLCAweDg0MzdhYTg4LCAweDdkMjlkYzk2LCAweDI3NTZkM2RjLFxuICAgIDB4OGI5MDdjZWUsIDB4YjUxZmQyNDAsIDB4ZTdjMDdjZTMsIDB4ZTU2NmI0YTEsIDB4YzNlOTYxNWUsIDB4M2NmODIwOWQsIDB4NjA5NGQxZTMsIDB4Y2Q5Y2EzNDEsXG4gICAgMHg1Yzc2NDYwZSwgMHgwMGVhOTgzYiwgMHhkNGQ2Nzg4MSwgMHhmZDQ3NTcyYywgMHhmNzZjZWRkOSwgMHhiZGE4MjI5YywgMHgxMjdkYWRhYSwgMHg0MzhhMDc0ZSxcbiAgICAweDFmOTdjMDkwLCAweDA4MWJkYjhhLCAweDkzYTA3ZWJlLCAweGI5MzhjYTE1LCAweDk3YjAzY2ZmLCAweDNkYzJjMGY4LCAweDhkMWFiMmVjLCAweDY0MzgwZTUxLFxuICAgIDB4NjhjYzdiZmIsIDB4ZDkwZjI3ODgsIDB4MTI0OTAxODEsIDB4NWRlNWZmZDQsIDB4ZGQ3ZWY4NmEsIDB4NzZhMmUyMTQsIDB4YjlhNDAzNjgsIDB4OTI1ZDk1OGYsXG4gICAgMHg0YjM5ZmZmYSwgMHhiYTM5YWVlOSwgMHhhNGZmZDMwYiwgMHhmYWY3OTMzYiwgMHg2ZDQ5ODYyMywgMHgxOTNjYmNmYSwgMHgyNzYyNzU0NSwgMHg4MjVjZjQ3YSxcbiAgICAweDYxYmQ4YmEwLCAweGQxMWU0MmQxLCAweGNlYWQwNGY0LCAweDEyN2VhMzkyLCAweDEwNDI4ZGI3LCAweDgyNzJhOTcyLCAweDkyNzBjNGE4LCAweDEyN2RlNTBiLFxuICAgIDB4Mjg1YmExYzgsIDB4M2M2MmY0NGYsIDB4MzVjMGVhYTUsIDB4ZTgwNWQyMzEsIDB4NDI4OTI5ZmIsIDB4YjRmY2RmODIsIDB4NGZiNjZhNTMsIDB4MGU3ZGMxNWIsXG4gICAgMHgxZjA4MWZhYiwgMHgxMDg2MThhZSwgMHhmY2ZkMDg2ZCwgMHhmOWZmMjg4OSwgMHg2OTRiY2MxMSwgMHgyMzZhNWNhZSwgMHgxMmRlY2E0ZCwgMHgyYzNmOGNjNSxcbiAgICAweGQyZDAyZGZlLCAweGY4ZWY1ODk2LCAweGU0Y2Y1MmRhLCAweDk1MTU1YjY3LCAweDQ5NGE0ODhjLCAweGI5YjZhODBjLCAweDVjOGY4MmJjLCAweDg5ZDM2YjQ1LFxuICAgIDB4M2E2MDk0MzcsIDB4ZWMwMGM5YTksIDB4NDQ3MTUyNTMsIDB4MGE4NzRiNDksIDB4ZDc3M2JjNDAsIDB4N2MzNDY3MWMsIDB4MDI3MTdlZjYsIDB4NGZlYjU1MzYsXG4gICAgMHhhMmQwMmZmZiwgMHhkMmJmNjBjNCwgMHhkNDNmMDNjMCwgMHg1MGI0ZWY2ZCwgMHgwNzQ3OGNkMSwgMHgwMDZlMTg4OCwgMHhhMmU1M2Y1NSwgMHhiOWU2ZDRiYyxcbiAgICAweGEyMDQ4MDE2LCAweDk3NTczODMzLCAweGQ3MjA3ZDY3LCAweGRlMGY4ZjNkLCAweDcyZjg3YjMzLCAweGFiY2M0ZjMzLCAweDc2ODhjNTVkLCAweDdiMDBhNmIwLFxuICAgIDB4OTQ3YjAwMDEsIDB4NTcwMDc1ZDIsIDB4ZjliYjg4ZjgsIDB4ODk0MjAxOWUsIDB4NDI2NGE1ZmYsIDB4ODU2MzAyZTAsIDB4NzJkYmQ5MmIsIDB4ZWU5NzFiNjksXG4gICAgMHg2ZWEyMmZkZSwgMHg1ZjA4YWUyYiwgMHhhZjdhNjE2ZCwgMHhlNWM5ODc2NywgMHhjZjFmZWJkMiwgMHg2MWVmYzhjMiwgMHhmMWFjMjU3MSwgMHhjYzgyMzljMixcbiAgICAweDY3MjE0Y2I4LCAweGIxZTU4M2QxLCAweGI3ZGMzZTYyLCAweDdmMTBiZGNlLCAweGY5MGE1YzM4LCAweDBmZjA0NDNkLCAweDYwNmU2ZGM2LCAweDYwNTQzYTQ5LFxuICAgIDB4NTcyN2MxNDgsIDB4MmJlOThhMWQsIDB4OGFiNDE3MzgsIDB4MjBlMWJlMjQsIDB4YWY5NmRhMGYsIDB4Njg0NTg0MjUsIDB4OTk4MzNiZTUsIDB4NjAwZDQ1N2QsXG4gICAgMHgyODJmOTM1MCwgMHg4MzM0YjM2MiwgMHhkOTFkMTEyMCwgMHgyYjZkOGRhMCwgMHg2NDJiMWUzMSwgMHg5YzMwNWEwMCwgMHg1MmJjZTY4OCwgMHgxYjAzNTg4YSxcbiAgICAweGY3YmFlZmQ1LCAweDQxNDJlZDljLCAweGE0MzE1YzExLCAweDgzMzIzZWM1LCAweGRmZWY0NjM2LCAweGExMzNjNTAxLCAweGU5ZDM1MzFjLCAweGVlMzUzNzgzKTtcblxuICBzQm94WzNdID0gbmV3IEFycmF5KFxuICAgIDB4OWRiMzA0MjAsIDB4MWZiNmU5ZGUsIDB4YTdiZTdiZWYsIDB4ZDI3M2EyOTgsIDB4NGE0ZjdiZGIsIDB4NjRhZDhjNTcsIDB4ODU1MTA0NDMsIDB4ZmEwMjBlZDEsXG4gICAgMHg3ZTI4N2FmZiwgMHhlNjBmYjY2MywgMHgwOTVmMzVhMSwgMHg3OWViZjEyMCwgMHhmZDA1OWQ0MywgMHg2NDk3YjdiMSwgMHhmMzY0MWY2MywgMHgyNDFlNGFkZixcbiAgICAweDI4MTQ3ZjVmLCAweDRmYTJiOGNkLCAweGM5NDMwMDQwLCAweDBjYzMyMjIwLCAweGZkZDMwYjMwLCAweGMwYTUzNzRmLCAweDFkMmQwMGQ5LCAweDI0MTQ3YjE1LFxuICAgIDB4ZWU0ZDExMWEsIDB4MGZjYTUxNjcsIDB4NzFmZjkwNGMsIDB4MmQxOTVmZmUsIDB4MWEwNTY0NWYsIDB4MGMxM2ZlZmUsIDB4MDgxYjA4Y2EsIDB4MDUxNzAxMjEsXG4gICAgMHg4MDUzMDEwMCwgMHhlODNlNWVmZSwgMHhhYzlhZjRmOCwgMHg3ZmU3MjcwMSwgMHhkMmI4ZWU1ZiwgMHgwNmRmNDI2MSwgMHhiYjllOWI4YSwgMHg3MjkzZWEyNSxcbiAgICAweGNlODRmZmRmLCAweGY1NzE4ODAxLCAweDNkZDY0YjA0LCAweGEyNmYyNjNiLCAweDdlZDQ4NDAwLCAweDU0N2VlYmU2LCAweDQ0NmQ0Y2EwLCAweDZjZjNkNmY1LFxuICAgIDB4MjY0OWFiZGYsIDB4YWVhMGM3ZjUsIDB4MzYzMzhjYzEsIDB4NTAzZjdlOTMsIDB4ZDM3NzIwNjEsIDB4MTFiNjM4ZTEsIDB4NzI1MDBlMDMsIDB4ZjgwZWIyYmIsXG4gICAgMHhhYmUwNTAyZSwgMHhlYzhkNzdkZSwgMHg1Nzk3MWU4MSwgMHhlMTRmNjc0NiwgMHhjOTMzNTQwMCwgMHg2OTIwMzE4ZiwgMHgwODFkYmI5OSwgMHhmZmMzMDRhNSxcbiAgICAweDRkMzUxODA1LCAweDdmM2Q1Y2UzLCAweGE2Yzg2NmM2LCAweDVkNWJjY2E5LCAweGRhZWM2ZmVhLCAweDlmOTI2ZjkxLCAweDlmNDYyMjJmLCAweDM5OTE0NjdkLFxuICAgIDB4YTViZjZkOGUsIDB4MTE0M2M0NGYsIDB4NDM5NTgzMDIsIDB4ZDAyMTRlZWIsIDB4MDIyMDgzYjgsIDB4M2ZiNjE4MGMsIDB4MThmODkzMWUsIDB4MjgxNjU4ZTYsXG4gICAgMHgyNjQ4NmUzZSwgMHg4YmQ3OGE3MCwgMHg3NDc3ZTRjMSwgMHhiNTA2ZTA3YywgMHhmMzJkMGEyNSwgMHg3OTA5OGIwMiwgMHhlNGVhYmI4MSwgMHgyODEyM2IyMyxcbiAgICAweDY5ZGVhZDM4LCAweDE1NzRjYTE2LCAweGRmODcxYjYyLCAweDIxMWM0MGI3LCAweGE1MWE5ZWY5LCAweDAwMTQzNzdiLCAweDA0MWU4YWM4LCAweDA5MTE0MDAzLFxuICAgIDB4YmQ1OWU0ZDIsIDB4ZTNkMTU2ZDUsIDB4NGZlODc2ZDUsIDB4MmY5MWEzNDAsIDB4NTU3YmU4ZGUsIDB4MDBlYWU0YTcsIDB4MGNlNWMyZWMsIDB4NGRiNGJiYTYsXG4gICAgMHhlNzU2YmRmZiwgMHhkZDMzNjlhYywgMHhlYzE3YjAzNSwgMHgwNjU3MjMyNywgMHg5OWFmYzhiMCwgMHg1NmM4YzM5MSwgMHg2YjY1ODExYywgMHg1ZTE0NjExOSxcbiAgICAweDZlODVjYjc1LCAweGJlMDdjMDAyLCAweGMyMzI1NTc3LCAweDg5M2ZmNGVjLCAweDViYmZjOTJkLCAweGQwZWMzYjI1LCAweGI3ODAxYWI3LCAweDhkNmQzYjI0LFxuICAgIDB4MjBjNzYzZWYsIDB4YzM2NmE1ZmMsIDB4OWMzODI4ODAsIDB4MGFjZTMyMDUsIDB4YWFjOTU0OGEsIDB4ZWNhMWQ3YzcsIDB4MDQxYWZhMzIsIDB4MWQxNjYyNWEsXG4gICAgMHg2NzAxOTAyYywgMHg5Yjc1N2E1NCwgMHgzMWQ0NzdmNywgMHg5MTI2YjAzMSwgMHgzNmNjNmZkYiwgMHhjNzBiOGI0NiwgMHhkOWU2NmE0OCwgMHg1NmU1NWE3OSxcbiAgICAweDAyNmE0Y2ViLCAweDUyNDM3ZWZmLCAweDJmOGY3NmI0LCAweDBkZjk4MGE1LCAweDg2NzRjZGUzLCAweGVkZGEwNGViLCAweDE3YTliZTA0LCAweDJjMThmNGRmLFxuICAgIDB4Yjc3NDdmOWQsIDB4YWIyYWY3YjQsIDB4ZWZjMzRkMjAsIDB4MmUwOTZiN2MsIDB4MTc0MWEyNTQsIDB4ZTViNmEwMzUsIDB4MjEzZDQyZjYsIDB4MmMxYzdjMjYsXG4gICAgMHg2MWMyZjUwZiwgMHg2NTUyZGFmOSwgMHhkMmMyMzFmOCwgMHgyNTEzMGY2OSwgMHhkODE2N2ZhMiwgMHgwNDE4ZjJjOCwgMHgwMDFhOTZhNiwgMHgwZDE1MjZhYixcbiAgICAweDYzMzE1YzIxLCAweDVlMGE3MmVjLCAweDQ5YmFmZWZkLCAweDE4NzkwOGQ5LCAweDhkMGRiZDg2LCAweDMxMTE3MGE3LCAweDNlOWI2NDBjLCAweGNjM2UxMGQ3LFxuICAgIDB4ZDVjYWQzYjYsIDB4MGNhZWMzODgsIDB4ZjczMDAxZTEsIDB4NmM3MjhhZmYsIDB4NzFlYWUyYTEsIDB4MWY5YWYzNmUsIDB4Y2ZjYmQxMmYsIDB4YzFkZTg0MTcsXG4gICAgMHhhYzA3YmU2YiwgMHhjYjQ0YTFkOCwgMHg4YjliMGY1NiwgMHgwMTM5ODhjMywgMHhiMWM1MmZjYSwgMHhiNGJlMzFjZCwgMHhkODc4MjgwNiwgMHgxMmEzYTRlMixcbiAgICAweDZmN2RlNTMyLCAweDU4ZmQ3ZWI2LCAweGQwMWVlOTAwLCAweDI0YWRmZmMyLCAweGY0OTkwZmM1LCAweDk3MTFhYWM1LCAweDAwMWQ3Yjk1LCAweDgyZTVlN2QyLFxuICAgIDB4MTA5ODczZjYsIDB4MDA2MTMwOTYsIDB4YzMyZDk1MjEsIDB4YWRhMTIxZmYsIDB4Mjk5MDg0MTUsIDB4N2ZiYjk3N2YsIDB4YWY5ZWIzZGIsIDB4MjljOWVkMmEsXG4gICAgMHg1Y2UyYTQ2NSwgMHhhNzMwZjMyYywgMHhkMGFhM2ZlOCwgMHg4YTVjYzA5MSwgMHhkNDllMmNlNywgMHgwY2U0NTRhOSwgMHhkNjBhY2Q4NiwgMHgwMTVmMTkxOSxcbiAgICAweDc3MDc5MTAzLCAweGRlYTAzYWY2LCAweDc4YTg1NjVlLCAweGRlZTM1NmRmLCAweDIxZjA1Y2JlLCAweDhiNzVlMzg3LCAweGIzYzUwNjUxLCAweGI4YTVjM2VmLFxuICAgIDB4ZDhlZWI2ZDIsIDB4ZTUyM2JlNzcsIDB4YzIxNTQ1MjksIDB4MmY2OWVmZGYsIDB4YWZlNjdhZmIsIDB4ZjQ3MGM0YjIsIDB4ZjNlMGViNWIsIDB4ZDZjYzk4NzYsXG4gICAgMHgzOWU0NDYwYywgMHgxZmRhODUzOCwgMHgxOTg3ODMyZiwgMHhjYTAwNzM2NywgMHhhOTkxNDRmOCwgMHgyOTZiMjk5ZSwgMHg0OTJmYzI5NSwgMHg5MjY2YmVhYixcbiAgICAweGI1Njc2ZTY5LCAweDliZDNkZGRhLCAweGRmN2UwNTJmLCAweGRiMjU3MDFjLCAweDFiNWU1MWVlLCAweGY2NTMyNGU2LCAweDZhZmNlMzZjLCAweDAzMTZjYzA0LFxuICAgIDB4ODY0NDIxM2UsIDB4YjdkYzU5ZDAsIDB4Nzk2NTI5MWYsIDB4Y2NkNmZkNDMsIDB4NDE4MjM5NzksIDB4OTMyYmNkZjYsIDB4YjY1N2MzNGQsIDB4NGVkZmQyODIsXG4gICAgMHg3YWU1MjkwYywgMHgzY2I5NTM2YiwgMHg4NTFlMjBmZSwgMHg5ODMzNTU3ZSwgMHgxM2VjZjBiMCwgMHhkM2ZmYjM3MiwgMHgzZjg1YzVjMSwgMHgwYWVmN2VkMik7XG5cbiAgc0JveFs0XSA9IG5ldyBBcnJheShcbiAgICAweDdlYzkwYzA0LCAweDJjNmU3NGI5LCAweDliMGU2NmRmLCAweGE2MzM3OTExLCAweGI4NmE3ZmZmLCAweDFkZDM1OGY1LCAweDQ0ZGQ5ZDQ0LCAweDE3MzExNjdmLFxuICAgIDB4MDhmYmYxZmEsIDB4ZTdmNTExY2MsIDB4ZDIwNTFiMDAsIDB4NzM1YWJhMDAsIDB4MmFiNzIyZDgsIDB4Mzg2MzgxY2IsIDB4YWNmNjI0M2EsIDB4NjliZWZkN2EsXG4gICAgMHhlNmEyZTc3ZiwgMHhmMGM3MjBjZCwgMHhjNDQ5NDgxNiwgMHhjY2Y1YzE4MCwgMHgzODg1MTY0MCwgMHgxNWIwYTg0OCwgMHhlNjhiMThjYiwgMHg0Y2FhZGVmZixcbiAgICAweDVmNDgwYTAxLCAweDA0MTJiMmFhLCAweDI1OTgxNGZjLCAweDQxZDBlZmUyLCAweDRlNDBiNDhkLCAweDI0OGViNmZiLCAweDhkYmExY2ZlLCAweDQxYTk5YjAyLFxuICAgIDB4MWE1NTBhMDQsIDB4YmE4ZjY1Y2IsIDB4NzI1MWY0ZTcsIDB4OTVhNTE3MjUsIDB4YzEwNmVjZDcsIDB4OTdhNTk4MGEsIDB4YzUzOWI5YWEsIDB4NGQ3OWZlNmEsXG4gICAgMHhmMmYzZjc2MywgMHg2OGFmODA0MCwgMHhlZDBjOWU1NiwgMHgxMWI0OTU4YiwgMHhlMWViNWE4OCwgMHg4NzA5ZTZiMCwgMHhkN2UwNzE1NiwgMHg0ZTI5ZmVhNyxcbiAgICAweDYzNjZlNTJkLCAweDAyZDFjMDAwLCAweGM0YWM4ZTA1LCAweDkzNzdmNTcxLCAweDBjMDUzNzJhLCAweDU3ODUzNWYyLCAweDIyNjFiZTAyLCAweGQ2NDJhMGM5LFxuICAgIDB4ZGYxM2EyODAsIDB4NzRiNTViZDIsIDB4NjgyMTk5YzAsIDB4ZDQyMWU1ZWMsIDB4NTNmYjNjZTgsIDB4YzhhZGVkYjMsIDB4MjhhODdmYzksIDB4M2Q5NTk5ODEsXG4gICAgMHg1YzFmZjkwMCwgMHhmZTM4ZDM5OSwgMHgwYzRlZmYwYiwgMHgwNjI0MDdlYSwgMHhhYTJmNGZiMSwgMHg0ZmI5Njk3NiwgMHg5MGM3OTUwNSwgMHhiMGE4YTc3NCxcbiAgICAweGVmNTVhMWZmLCAweGU1OWNhMmMyLCAweGE2YjYyZDI3LCAweGU2NmE0MjYzLCAweGRmNjUwMDFmLCAweDBlYzUwOTY2LCAweGRmZGQ1NWJjLCAweDI5ZGUwNjU1LFxuICAgIDB4OTExZTczOWEsIDB4MTdhZjg5NzUsIDB4MzJjNzkxMWMsIDB4ODlmODk0NjgsIDB4MGQwMWU5ODAsIDB4NTI0NzU1ZjQsIDB4MDNiNjNjYzksIDB4MGNjODQ0YjIsXG4gICAgMHhiY2YzZjBhYSwgMHg4N2FjMzZlOSwgMHhlNTNhNzQyNiwgMHgwMWIzZDgyYiwgMHgxYTllNzQ0OSwgMHg2NGVlMmQ3ZSwgMHhjZGRiYjFkYSwgMHgwMWM5NDkxMCxcbiAgICAweGI4NjhiZjgwLCAweDBkMjZmM2ZkLCAweDkzNDJlZGU3LCAweDA0YTVjMjg0LCAweDYzNjczN2I2LCAweDUwZjViNjE2LCAweGYyNDc2NmUzLCAweDhlY2EzNmMxLFxuICAgIDB4MTM2ZTA1ZGIsIDB4ZmVmMTgzOTEsIDB4ZmI4ODdhMzcsIDB4ZDZlN2Y3ZDQsIDB4YzdmYjdkYzksIDB4MzA2M2ZjZGYsIDB4YjZmNTg5ZGUsIDB4ZWMyOTQxZGEsXG4gICAgMHgyNmU0NjY5NSwgMHhiNzU2NjQxOSwgMHhmNjU0ZWZjNSwgMHhkMDhkNThiNywgMHg0ODkyNTQwMSwgMHhjMWJhY2I3ZiwgMHhlNWZmNTUwZiwgMHhiNjA4MzA0OSxcbiAgICAweDViYjVkMGU4LCAweDg3ZDcyZTVhLCAweGFiNmE2ZWUxLCAweDIyM2E2NmNlLCAweGM2MmJmM2NkLCAweDllMDg4NWY5LCAweDY4Y2IzZTQ3LCAweDA4NmMwMTBmLFxuICAgIDB4YTIxZGU4MjAsIDB4ZDE4YjY5ZGUsIDB4ZjNmNjU3NzcsIDB4ZmEwMmMzZjYsIDB4NDA3ZWRhYzMsIDB4Y2JiM2Q1NTAsIDB4MTc5MzA4NGQsIDB4YjBkNzBlYmEsXG4gICAgMHgwYWIzNzhkNSwgMHhkOTUxZmIwYywgMHhkZWQ3ZGE1NiwgMHg0MTI0YmJlNCwgMHg5NGNhMGI1NiwgMHgwZjU3NTVkMSwgMHhlMGUxZTU2ZSwgMHg2MTg0YjViZSxcbiAgICAweDU4MGEyNDlmLCAweDk0Zjc0YmMwLCAweGUzMjc4ODhlLCAweDlmN2I1NTYxLCAweGMzZGMwMjgwLCAweDA1Njg3NzE1LCAweDY0NmM2YmQ3LCAweDQ0OTA0ZGIzLFxuICAgIDB4NjZiNGYwYTMsIDB4YzBmMTY0OGEsIDB4Njk3ZWQ1YWYsIDB4NDllOTJmZjYsIDB4MzA5ZTM3NGYsIDB4MmNiNjM1NmEsIDB4ODU4MDg1NzMsIDB4NDk5MWY4NDAsXG4gICAgMHg3NmYwYWUwMiwgMHgwODNiZTg0ZCwgMHgyODQyMWM5YSwgMHg0NDQ4OTQwNiwgMHg3MzZlNGNiOCwgMHhjMTA5MjkxMCwgMHg4YmM5NWZjNiwgMHg3ZDg2OWNmNCxcbiAgICAweDEzNGY2MTZmLCAweDJlNzcxMThkLCAweGIzMWIyYmUxLCAweGFhOTBiNDcyLCAweDNjYTVkNzE3LCAweDdkMTYxYmJhLCAweDljYWQ5MDEwLCAweGFmNDYyYmEyLFxuICAgIDB4OWZlNDU5ZDIsIDB4NDVkMzQ1NTksIDB4ZDlmMmRhMTMsIDB4ZGJjNjU0ODcsIDB4ZjNlNGY5NGUsIDB4MTc2ZDQ4NmYsIDB4MDk3YzEzZWEsIDB4NjMxZGE1YzcsXG4gICAgMHg0NDVmNzM4MiwgMHgxNzU2ODNmNCwgMHhjZGM2NmE5NywgMHg3MGJlMDI4OCwgMHhiM2NkY2Y3MiwgMHg2ZTVkZDJmMywgMHgyMDkzNjA3OSwgMHg0NTliODBhNSxcbiAgICAweGJlNjBlMmRiLCAweGE5YzIzMTAxLCAweGViYTUzMTVjLCAweDIyNGU0MmYyLCAweDFjNWMxNTcyLCAweGY2NzIxYjJjLCAweDFhZDJmZmYzLCAweDhjMjU0MDRlLFxuICAgIDB4MzI0ZWQ3MmYsIDB4NDA2N2I3ZmQsIDB4MDUyMzEzOGUsIDB4NWNhM2JjNzgsIDB4ZGMwZmQ2NmUsIDB4NzU5MjIyODMsIDB4Nzg0ZDZiMTcsIDB4NThlYmIxNmUsXG4gICAgMHg0NDA5NGY4NSwgMHgzZjQ4MWQ4NywgMHhmY2ZlYWU3YiwgMHg3N2I1ZmY3NiwgMHg4YzIzMDJiZiwgMHhhYWY0NzU1NiwgMHg1ZjQ2YjAyYSwgMHgyYjA5MjgwMSxcbiAgICAweDNkMzhmNWY3LCAweDBjYTgxZjM2LCAweDUyYWY0YThhLCAweDY2ZDVlN2MwLCAweGRmM2IwODc0LCAweDk1MDU1MTEwLCAweDFiNWFkN2E4LCAweGY2MWVkNWFkLFxuICAgIDB4NmNmNmU0NzksIDB4MjA3NTgxODQsIDB4ZDBjZWZhNjUsIDB4ODhmN2JlNTgsIDB4NGEwNDY4MjYsIDB4MGZmNmY4ZjMsIDB4YTA5YzdmNzAsIDB4NTM0NmFiYTAsXG4gICAgMHg1Y2U5NmMyOCwgMHhlMTc2ZWRhMywgMHg2YmFjMzA3ZiwgMHgzNzY4MjlkMiwgMHg4NTM2MGZhOSwgMHgxN2UzZmUyYSwgMHgyNGI3OTc2NywgMHhmNWE5NmIyMCxcbiAgICAweGQ2Y2QyNTk1LCAweDY4ZmYxZWJmLCAweDc1NTU0NDJjLCAweGYxOWYwNmJlLCAweGY5ZTA2NTlhLCAweGVlYjk0OTFkLCAweDM0MDEwNzE4LCAweGJiMzBjYWI4LFxuICAgIDB4ZTgyMmZlMTUsIDB4ODg1NzA5ODMsIDB4NzUwZTYyNDksIDB4ZGE2MjdlNTUsIDB4NWU3NmZmYTgsIDB4YjE1MzQ1NDYsIDB4NmQ0N2RlMDgsIDB4ZWZlOWU3ZDQpO1xuXG4gIHNCb3hbNV0gPSBuZXcgQXJyYXkoXG4gICAgMHhmNmZhOGY5ZCwgMHgyY2FjNmNlMSwgMHg0Y2EzNDg2NywgMHhlMjMzN2Y3YywgMHg5NWRiMDhlNywgMHgwMTY4NDNiNCwgMHhlY2VkNWNiYywgMHgzMjU1NTNhYyxcbiAgICAweGJmOWYwOTYwLCAweGRmYTFlMmVkLCAweDgzZjA1NzlkLCAweDYzZWQ4NmI5LCAweDFhYjZhNmI4LCAweGRlNWViZTM5LCAweGYzOGZmNzMyLCAweDg5ODliMTM4LFxuICAgIDB4MzNmMTQ5NjEsIDB4YzAxOTM3YmQsIDB4ZjUwNmM2ZGEsIDB4ZTQ2MjVlN2UsIDB4YTMwOGVhOTksIDB4NGUyM2UzM2MsIDB4NzljYmQ3Y2MsIDB4NDhhMTQzNjcsXG4gICAgMHhhMzE0OTYxOSwgMHhmZWM5NGJkNSwgMHhhMTE0MTc0YSwgMHhlYWEwMTg2NiwgMHhhMDg0ZGIyZCwgMHgwOWE4NDg2ZiwgMHhhODg4NjE0YSwgMHgyOTAwYWY5OCxcbiAgICAweDAxNjY1OTkxLCAweGUxOTkyODYzLCAweGM4ZjMwYzYwLCAweDJlNzhlZjNjLCAweGQwZDUxOTMyLCAweGNmMGZlYzE0LCAweGY3Y2EwN2QyLCAweGQwYTgyMDcyLFxuICAgIDB4ZmQ0MTE5N2UsIDB4OTMwNWE2YjAsIDB4ZTg2YmUzZGEsIDB4NzRiZWQzY2QsIDB4MzcyZGE1M2MsIDB4NGM3ZjQ0NDgsIDB4ZGFiNWQ0NDAsIDB4NmRiYTBlYzMsXG4gICAgMHgwODM5MTlhNywgMHg5ZmJhZWVkOSwgMHg0OWRiY2ZiMCwgMHg0ZTY3MGM1MywgMHg1YzNkOWMwMSwgMHg2NGJkYjk0MSwgMHgyYzBlNjM2YSwgMHhiYTdkZDljZCxcbiAgICAweGVhNmY3Mzg4LCAweGU3MGJjNzYyLCAweDM1ZjI5YWRiLCAweDVjNGNkZDhkLCAweGYwZDQ4ZDhjLCAweGI4ODE1M2UyLCAweDA4YTE5ODY2LCAweDFhZTJlYWM4LFxuICAgIDB4Mjg0Y2FmODksIDB4YWE5MjgyMjMsIDB4OTMzNGJlNTMsIDB4M2IzYTIxYmYsIDB4MTY0MzRiZTMsIDB4OWFlYTM5MDYsIDB4ZWZlOGMzNmUsIDB4Zjg5MGNkZDksXG4gICAgMHg4MDIyNmRhZSwgMHhjMzQwYTRhMywgMHhkZjdlOWMwOSwgMHhhNjk0YTgwNywgMHg1YjdjNWVjYywgMHgyMjFkYjNhNiwgMHg5YTY5YTAyZiwgMHg2ODgxOGE1NCxcbiAgICAweGNlYjIyOTZmLCAweDUzYzA4NDNhLCAweGZlODkzNjU1LCAweDI1YmZlNjhhLCAweGI0NjI4YWJjLCAweGNmMjIyZWJmLCAweDI1YWM2ZjQ4LCAweGE5YTk5Mzg3LFxuICAgIDB4NTNiZGRiNjUsIDB4ZTc2ZmZiZTcsIDB4ZTk2N2ZkNzgsIDB4MGJhOTM1NjMsIDB4OGUzNDJiYzEsIDB4ZThhMTFiZTksIDB4NDk4MDc0MGQsIDB4YzgwODdkZmMsXG4gICAgMHg4ZGU0YmY5OSwgMHhhMTExMDFhMCwgMHg3ZmQzNzk3NSwgMHhkYTVhMjZjMCwgMHhlODFmOTk0ZiwgMHg5NTI4Y2Q4OSwgMHhmZDMzOWZlZCwgMHhiODc4MzRiZixcbiAgICAweDVmMDQ0NTZkLCAweDIyMjU4Njk4LCAweGM5YzRjODNiLCAweDJkYzE1NmJlLCAweDRmNjI4ZGFhLCAweDU3ZjU1ZWM1LCAweGUyMjIwYWJlLCAweGQyOTE2ZWJmLFxuICAgIDB4NGVjNzViOTUsIDB4MjRmMmMzYzAsIDB4NDJkMTVkOTksIDB4Y2QwZDdmYTAsIDB4N2I2ZTI3ZmYsIDB4YThkYzhhZjAsIDB4NzM0NWMxMDYsIDB4ZjQxZTIzMmYsXG4gICAgMHgzNTE2MjM4NiwgMHhlNmVhODkyNiwgMHgzMzMzYjA5NCwgMHgxNTdlYzZmMiwgMHgzNzJiNzRhZiwgMHg2OTI1NzNlNCwgMHhlOWE5ZDg0OCwgMHhmMzE2MDI4OSxcbiAgICAweDNhNjJlZjFkLCAweGE3ODdlMjM4LCAweGYzYTVmNjc2LCAweDc0MzY0ODUzLCAweDIwOTUxMDYzLCAweDQ1NzY2OThkLCAweGI2ZmFkNDA3LCAweDU5MmFmOTUwLFxuICAgIDB4MzZmNzM1MjMsIDB4NGNmYjZlODcsIDB4N2RhNGNlYzAsIDB4NmMxNTJkYWEsIDB4Y2IwMzk2YTgsIDB4YzUwZGZlNWQsIDB4ZmNkNzA3YWIsIDB4MDkyMWM0MmYsXG4gICAgMHg4OWRmZjBiYiwgMHg1ZmUyYmU3OCwgMHg0NDhmNGYzMywgMHg3NTQ2MTNjOSwgMHgyYjA1ZDA4ZCwgMHg0OGI5ZDU4NSwgMHhkYzA0OTQ0MSwgMHhjODA5OGY5YixcbiAgICAweDdkZWRlNzg2LCAweGMzOWEzMzczLCAweDQyNDEwMDA1LCAweDZhMDkxNzUxLCAweDBlZjNjOGE2LCAweDg5MDA3MmQ2LCAweDI4MjA3NjgyLCAweGE5YTlmN2JlLFxuICAgIDB4YmYzMjY3OWQsIDB4ZDQ1YjViNzUsIDB4YjM1M2ZkMDAsIDB4Y2JiMGUzNTgsIDB4ODMwZjIyMGEsIDB4MWY4ZmIyMTQsIDB4ZDM3MmNmMDgsIDB4Y2MzYzRhMTMsXG4gICAgMHg4Y2Y2MzE2NiwgMHgwNjFjODdiZSwgMHg4OGM5OGY4OCwgMHg2MDYyZTM5NywgMHg0N2NmOGU3YSwgMHhiNmM4NTI4MywgMHgzY2MyYWNmYiwgMHgzZmMwNjk3NixcbiAgICAweDRlOGYwMjUyLCAweDY0ZDgzMTRkLCAweGRhMzg3MGUzLCAweDFlNjY1NDU5LCAweGMxMDkwOGYwLCAweDUxMzAyMWE1LCAweDZjNWI2OGI3LCAweDgyMmY4YWEwLFxuICAgIDB4MzAwN2NkM2UsIDB4NzQ3MTllZWYsIDB4ZGM4NzI2ODEsIDB4MDczMzQwZDQsIDB4N2U0MzJmZDksIDB4MGM1ZWMyNDEsIDB4ODgwOTI4NmMsIDB4ZjU5MmQ4OTEsXG4gICAgMHgwOGE5MzBmNiwgMHg5NTdlZjMwNSwgMHhiN2ZiZmZiZCwgMHhjMjY2ZTk2ZiwgMHg2ZmU0YWM5OCwgMHhiMTczZWNjMCwgMHhiYzYwYjQyYSwgMHg5NTM0OThkYSxcbiAgICAweGZiYTFhZTEyLCAweDJkNGJkNzM2LCAweDBmMjVmYWFiLCAweGE0ZjNmY2ViLCAweGUyOTY5MTIzLCAweDI1N2YwYzNkLCAweDkzNDhhZjQ5LCAweDM2MTQwMGJjLFxuICAgIDB4ZTg4MTZmNGEsIDB4MzgxNGYyMDAsIDB4YTNmOTQwNDMsIDB4OWM3YTU0YzIsIDB4YmM3MDRmNTcsIDB4ZGE0MWU3ZjksIDB4YzI1YWQzM2EsIDB4NTRmNGEwODQsXG4gICAgMHhiMTdmNTUwNSwgMHg1OTM1N2NiZSwgMHhlZGJkMTVjOCwgMHg3Zjk3YzVhYiwgMHhiYTVhYzdiNSwgMHhiNmY2ZGVhZiwgMHgzYTQ3OWMzYSwgMHg1MzAyZGEyNSxcbiAgICAweDY1M2Q3ZTZhLCAweDU0MjY4ZDQ5LCAweDUxYTQ3N2VhLCAweDUwMTdkNTViLCAweGQ3ZDI1ZDg4LCAweDQ0MTM2Yzc2LCAweDA0MDRhOGM4LCAweGI4ZTVhMTIxLFxuICAgIDB4YjgxYTkyOGEsIDB4NjBlZDU4NjksIDB4OTdjNTViOTYsIDB4ZWFlYzk5MWIsIDB4Mjk5MzU5MTMsIDB4MDFmZGI3ZjEsIDB4MDg4ZThkZmEsIDB4OWFiNmY2ZjUsXG4gICAgMHgzYjRjYmY5ZiwgMHg0YTVkZTNhYiwgMHhlNjA1MWQzNSwgMHhhMGUxZDg1NSwgMHhkMzZiNGNmMSwgMHhmNTQ0ZWRlYiwgMHhiMGU5MzUyNCwgMHhiZWJiOGZiZCxcbiAgICAweGEyZDc2MmNmLCAweDQ5YzkyZjU0LCAweDM4YjVmMzMxLCAweDcxMjhhNDU0LCAweDQ4MzkyOTA1LCAweGE2NWIxZGI4LCAweDg1MWM5N2JkLCAweGQ2NzVjZjJmKTtcblxuICBzQm94WzZdID0gbmV3IEFycmF5KFxuICAgIDB4ODVlMDQwMTksIDB4MzMyYmY1NjcsIDB4NjYyZGJmZmYsIDB4Y2ZjNjU2OTMsIDB4MmE4ZDdmNmYsIDB4YWI5YmM5MTIsIDB4ZGU2MDA4YTEsIDB4MjAyOGRhMWYsXG4gICAgMHgwMjI3YmNlNywgMHg0ZDY0MjkxNiwgMHgxOGZhYzMwMCwgMHg1MGYxOGI4MiwgMHgyY2IyY2IxMSwgMHhiMjMyZTc1YywgMHg0YjM2OTVmMiwgMHhiMjg3MDdkZSxcbiAgICAweGEwNWZiY2Y2LCAweGNkNDE4MWU5LCAweGUxNTAyMTBjLCAweGUyNGVmMWJkLCAweGIxNjhjMzgxLCAweGZkZTRlNzg5LCAweDVjNzliMGQ4LCAweDFlOGJmZDQzLFxuICAgIDB4NGQ0OTUwMDEsIDB4MzhiZTQzNDEsIDB4OTEzY2VlMWQsIDB4OTJhNzljM2YsIDB4MDg5NzY2YmUsIDB4YmFlZWFkZjQsIDB4MTI4NmJlY2YsIDB4YjZlYWNiMTksXG4gICAgMHgyNjYwYzIwMCwgMHg3NTY1YmRlNCwgMHg2NDI0MWY3YSwgMHg4MjQ4ZGNhOSwgMHhjM2IzYWQ2NiwgMHgyODEzNjA4NiwgMHgwYmQ4ZGZhOCwgMHgzNTZkMWNmMixcbiAgICAweDEwNzc4OWJlLCAweGIzYjJlOWNlLCAweDA1MDJhYThmLCAweDBiYzAzNTFlLCAweDE2NmJmNTJhLCAweGViMTJmZjgyLCAweGUzNDg2OTExLCAweGQzNGQ3NTE2LFxuICAgIDB4NGU3YjNhZmYsIDB4NWY0MzY3MWIsIDB4OWNmNmUwMzcsIDB4NDk4MWFjODMsIDB4MzM0MjY2Y2UsIDB4OGM5MzQxYjcsIDB4ZDBkODU0YzAsIDB4Y2IzYTZjODgsXG4gICAgMHg0N2JjMjgyOSwgMHg0NzI1YmEzNywgMHhhNjZhZDIyYiwgMHg3YWQ2MWYxZSwgMHgwYzVjYmFmYSwgMHg0NDM3ZjEwNywgMHhiNmU3OTk2MiwgMHg0MmQyZDgxNixcbiAgICAweDBhOTYxMjg4LCAweGUxYTVjMDZlLCAweDEzNzQ5ZTY3LCAweDcyZmMwODFhLCAweGIxZDEzOWY3LCAweGY5NTgzNzQ1LCAweGNmMTlkZjU4LCAweGJlYzNmNzU2LFxuICAgIDB4YzA2ZWJhMzAsIDB4MDcyMTFiMjQsIDB4NDVjMjg4MjksIDB4Yzk1ZTMxN2YsIDB4YmM4ZWM1MTEsIDB4MzhiYzQ2ZTksIDB4YzZlNmZhMTQsIDB4YmFlODU4NGEsXG4gICAgMHhhZDRlYmM0NiwgMHg0NjhmNTA4YiwgMHg3ODI5NDM1ZiwgMHhmMTI0MTgzYiwgMHg4MjFkYmE5ZiwgMHhhZmY2MGZmNCwgMHhlYTJjNGU2ZCwgMHgxNmUzOTI2NCxcbiAgICAweDkyNTQ0YThiLCAweDAwOWI0ZmMzLCAweGFiYTY4Y2VkLCAweDlhYzk2Zjc4LCAweDA2YTViNzlhLCAweGIyODU2ZTZlLCAweDFhZWMzY2E5LCAweGJlODM4Njg4LFxuICAgIDB4MGUwODA0ZTksIDB4NTVmMWJlNTYsIDB4ZTdlNTM2M2IsIDB4YjNhMWYyNWQsIDB4ZjdkZWJiODUsIDB4NjFmZTAzM2MsIDB4MTY3NDYyMzMsIDB4M2MwMzRjMjgsXG4gICAgMHhkYTZkMGM3NCwgMHg3OWFhYzU2YywgMHgzY2U0ZTFhZCwgMHg1MWYwYzgwMiwgMHg5OGY4ZjM1YSwgMHgxNjI2YTQ5ZiwgMHhlZWQ4MmIyOSwgMHgxZDM4MmZlMyxcbiAgICAweDBjNGZiOTlhLCAweGJiMzI1Nzc4LCAweDNlYzZkOTdiLCAweDZlNzdhNmE5LCAweGNiNjU4YjVjLCAweGQ0NTIzMGM3LCAweDJiZDE0MDhiLCAweDYwYzAzZWI3LFxuICAgIDB4YjkwNjhkNzgsIDB4YTMzNzU0ZjQsIDB4ZjQzMGM4N2QsIDB4YzhhNzEzMDIsIDB4Yjk2ZDhjMzIsIDB4ZWJkNGU3YmUsIDB4YmU4YjlkMmQsIDB4Nzk3OWZiMDYsXG4gICAgMHhlNzIyNTMwOCwgMHg4Yjc1Y2Y3NywgMHgxMWVmOGRhNCwgMHhlMDgzYzg1OCwgMHg4ZDZiNzg2ZiwgMHg1YTYzMTdhNiwgMHhmYTVjZjdhMCwgMHg1ZGRhMDAzMyxcbiAgICAweGYyOGViZmIwLCAweGY1YjljMzEwLCAweGEwZWFjMjgwLCAweDA4Yjk3NjdhLCAweGEzZDlkMmIwLCAweDc5ZDM0MjE3LCAweDAyMWE3MThkLCAweDlhYzYzMzZhLFxuICAgIDB4MjcxMWZkNjAsIDB4NDM4MDUwZTMsIDB4MDY5OTA4YTgsIDB4M2Q3ZmVkYzQsIDB4ODI2ZDJiZWYsIDB4NGVlYjg0NzYsIDB4NDg4ZGNmMjUsIDB4MzZjOWQ1NjYsXG4gICAgMHgyOGU3NGU0MSwgMHhjMjYxMGFjYSwgMHgzZDQ5YTljZiwgMHhiYWUzYjlkZiwgMHhiNjVmOGRlNiwgMHg5MmFlYWY2NCwgMHgzYWM3ZDVlNiwgMHg5ZWE4MDUwOSxcbiAgICAweGYyMmIwMTdkLCAweGE0MTczZjcwLCAweGRkMWUxNmMzLCAweDE1ZTBkN2Y5LCAweDUwYjFiODg3LCAweDJiOWY0ZmQ1LCAweDYyNWFiYTgyLCAweDZhMDE3OTYyLFxuICAgIDB4MmVjMDFiOWMsIDB4MTU0ODhhYTksIDB4ZDcxNmU3NDAsIDB4NDAwNTVhMmMsIDB4OTNkMjlhMjIsIDB4ZTMyZGJmOWEsIDB4MDU4NzQ1YjksIDB4MzQ1M2RjMWUsXG4gICAgMHhkNjk5Mjk2ZSwgMHg0OTZjZmY2ZiwgMHgxYzlmNDk4NiwgMHhkZmUyZWQwNywgMHhiODcyNDJkMSwgMHgxOWRlN2VhZSwgMHgwNTNlNTYxYSwgMHgxNWFkNmY4YyxcbiAgICAweDY2NjI2YzFjLCAweDcxNTRjMjRjLCAweGVhMDgyYjJhLCAweDkzZWIyOTM5LCAweDE3ZGNiMGYwLCAweDU4ZDRmMmFlLCAweDllYTI5NGZiLCAweDUyY2Y1NjRjLFxuICAgIDB4OTg4M2ZlNjYsIDB4MmVjNDA1ODEsIDB4NzYzOTUzYzMsIDB4MDFkNjY5MmUsIDB4ZDNhMGMxMDgsIDB4YTFlNzE2MGUsIDB4ZTRmMmRmYTYsIDB4NjkzZWQyODUsXG4gICAgMHg3NDkwNDY5OCwgMHg0YzJiMGVkZCwgMHg0Zjc1NzY1NiwgMHg1ZDM5MzM3OCwgMHhhMTMyMjM0ZiwgMHgzZDMyMWM1ZCwgMHhjM2Y1ZTE5NCwgMHg0YjI2OTMwMSxcbiAgICAweGM3OWYwMjJmLCAweDNjOTk3ZTdlLCAweDVlNGY5NTA0LCAweDNmZmFmYmJkLCAweDc2ZjdhZDBlLCAweDI5NjY5M2Y0LCAweDNkMWZjZTZmLCAweGM2MWU0NWJlLFxuICAgIDB4ZDNiNWFiMzQsIDB4ZjcyYmY5YjcsIDB4MWIwNDM0YzAsIDB4NGU3MmI1NjcsIDB4NTU5MmEzM2QsIDB4YjUyMjkzMDEsIDB4Y2ZkMmE4N2YsIDB4NjBhZWI3NjcsXG4gICAgMHgxODE0Mzg2YiwgMHgzMGJjYzMzZCwgMHgzOGEwYzA3ZCwgMHhmZDE2MDZmMiwgMHhjMzYzNTE5YiwgMHg1ODlkZDM5MCwgMHg1NDc5ZjhlNiwgMHgxY2I4ZDY0NyxcbiAgICAweDk3ZmQ2MWE5LCAweGVhNzc1OWY0LCAweDJkNTc1MzlkLCAweDU2OWE1OGNmLCAweGU4NGU2M2FkLCAweDQ2MmUxYjc4LCAweDY1ODBmODdlLCAweGYzODE3OTE0LFxuICAgIDB4OTFkYTU1ZjQsIDB4NDBhMjMwZjMsIDB4ZDE5ODhmMzUsIDB4YjZlMzE4ZDIsIDB4M2ZmYTUwYmMsIDB4M2Q0MGYwMjEsIDB4YzNjMGJkYWUsIDB4NDk1OGMyNGMsXG4gICAgMHg1MThmMzZiMiwgMHg4NGIxZDM3MCwgMHgwZmVkY2U4MywgMHg4NzhkZGFkYSwgMHhmMmEyNzljNywgMHg5NGUwMWJlOCwgMHg5MDcxNmY0YiwgMHg5NTRiOGFhMyk7XG5cbiAgc0JveFs3XSA9IG5ldyBBcnJheShcbiAgICAweGUyMTYzMDBkLCAweGJiZGRmZmZjLCAweGE3ZWJkYWJkLCAweDM1NjQ4MDk1LCAweDc3ODlmOGI3LCAweGU2YzExMjFiLCAweDBlMjQxNjAwLCAweDA1MmNlOGI1LFxuICAgIDB4MTFhOWNmYjAsIDB4ZTU5NTJmMTEsIDB4ZWNlNzk5MGEsIDB4OTM4NmQxNzQsIDB4MmE0MjkzMWMsIDB4NzZlMzgxMTEsIDB4YjEyZGVmM2EsIDB4MzdkZGRkZmMsXG4gICAgMHhkZTlhZGViMSwgMHgwYTBjYzMyYywgMHhiZTE5NzAyOSwgMHg4NGEwMDk0MCwgMHhiYjI0M2EwZiwgMHhiNGQxMzdjZiwgMHhiNDRlNzlmMCwgMHgwNDllZWRmZCxcbiAgICAweDBiMTVhMTVkLCAweDQ4MGQzMTY4LCAweDhiYmJkZTVhLCAweDY2OWRlZDQyLCAweGM3ZWNlODMxLCAweDNmOGY5NWU3LCAweDcyZGYxOTFiLCAweDc1ODAzMzBkLFxuICAgIDB4OTQwNzQyNTEsIDB4NWM3ZGNkZmEsIDB4YWJiZTZkNjMsIDB4YWE0MDIxNjQsIDB4YjMwMWQ0MGEsIDB4MDJlN2QxY2EsIDB4NTM1NzFkYWUsIDB4N2EzMTgyYTIsXG4gICAgMHgxMmE4ZGRlYywgMHhmZGFhMzM1ZCwgMHgxNzZmNDNlOCwgMHg3MWZiNDZkNCwgMHgzODEyOTAyMiwgMHhjZTk0OWFkNCwgMHhiODQ3NjlhZCwgMHg5NjViZDg2MixcbiAgICAweDgyZjNkMDU1LCAweDY2ZmI5NzY3LCAweDE1YjgwYjRlLCAweDFkNWI0N2EwLCAweDRjZmRlMDZmLCAweGMyOGVjNGI4LCAweDU3ZTg3MjZlLCAweDY0N2E3OGZjLFxuICAgIDB4OTk4NjVkNDQsIDB4NjA4YmQ1OTMsIDB4NmMyMDBlMDMsIDB4MzlkYzVmZjYsIDB4NWQwYjAwYTMsIDB4YWU2M2FmZjIsIDB4N2U4YmQ2MzIsIDB4NzAxMDhjMGMsXG4gICAgMHhiYmQzNTA0OSwgMHgyOTk4ZGYwNCwgMHg5ODBjZjQyYSwgMHg5YjZkZjQ5MSwgMHg5ZTdlZGQ1MywgMHgwNjkxODU0OCwgMHg1OGNiN2UwNywgMHgzYjc0ZWYyZSxcbiAgICAweDUyMmZmZmIxLCAweGQyNDcwOGNjLCAweDFjN2UyN2NkLCAweGE0ZWIyMTViLCAweDNjZjFkMmUyLCAweDE5YjQ3YTM4LCAweDQyNGY3NjE4LCAweDM1ODU2MDM5LFxuICAgIDB4OWQxN2RlZTcsIDB4MjdlYjM1ZTYsIDB4YzlhZmY2N2IsIDB4MzZiYWY1YjgsIDB4MDljNDY3Y2QsIDB4YzE4OTEwYjEsIDB4ZTExZGJmN2IsIDB4MDZjZDFhZjgsXG4gICAgMHg3MTcwYzYwOCwgMHgyZDVlMzM1NCwgMHhkNGRlNDk1YSwgMHg2NGM2ZDAwNiwgMHhiY2MwYzYyYywgMHgzZGQwMGRiMywgMHg3MDhmOGYzNCwgMHg3N2Q1MWI0MixcbiAgICAweDI2NGY2MjBmLCAweDI0YjhkMmJmLCAweDE1YzFiNzllLCAweDQ2YTUyNTY0LCAweGY4ZDdlNTRlLCAweDNlMzc4MTYwLCAweDc4OTVjZGE1LCAweDg1OWMxNWE1LFxuICAgIDB4ZTY0NTk3ODgsIDB4YzM3YmM3NWYsIDB4ZGIwN2JhMGMsIDB4MDY3NmEzYWIsIDB4N2YyMjliMWUsIDB4MzE4NDJlN2IsIDB4MjQyNTlmZDcsIDB4ZjhiZWY0NzIsXG4gICAgMHg4MzVmZmNiOCwgMHg2ZGY0YzFmMiwgMHg5NmY1YjE5NSwgMHhmZDBhZjBmYywgMHhiMGZlMTM0YywgMHhlMjUwNmQzZCwgMHg0ZjliMTJlYSwgMHhmMjE1ZjIyNSxcbiAgICAweGEyMjM3MzZmLCAweDlmYjRjNDI4LCAweDI1ZDA0OTc5LCAweDM0YzcxM2Y4LCAweGM0NjE4MTg3LCAweGVhN2E2ZTk4LCAweDdjZDE2ZWZjLCAweDE0MzY4NzZjLFxuICAgIDB4ZjE1NDQxMDcsIDB4YmVkZWVlMTQsIDB4NTZlOWFmMjcsIDB4YTA0YWE0NDEsIDB4M2NmN2M4OTksIDB4OTJlY2JhZTYsIDB4ZGQ2NzAxNmQsIDB4MTUxNjgyZWIsXG4gICAgMHhhODQyZWVkZiwgMHhmZGJhNjBiNCwgMHhmMTkwN2I3NSwgMHgyMGUzMDMwZiwgMHgyNGQ4YzI5ZSwgMHhlMTM5NjczYiwgMHhlZmE2M2ZiOCwgMHg3MTg3MzA1NCxcbiAgICAweGI2ZjJjZjNiLCAweDlmMzI2NDQyLCAweGNiMTVhNGNjLCAweGIwMWE0NTA0LCAweGYxZTQ3ZDhkLCAweDg0NGExYmU1LCAweGJhZTdkZmRjLCAweDQyY2JkYTcwLFxuICAgIDB4Y2Q3ZGFlMGEsIDB4NTdlODViN2EsIDB4ZDUzZjVhZjYsIDB4MjBjZjRkOGMsIDB4Y2VhNGQ0MjgsIDB4NzlkMTMwYTQsIDB4MzQ4NmViZmIsIDB4MzNkM2NkZGMsXG4gICAgMHg3Nzg1M2I1MywgMHgzN2VmZmNiNSwgMHhjNTA2ODc3OCwgMHhlNTgwYjNlNiwgMHg0ZTY4YjhmNCwgMHhjNWM4YjM3ZSwgMHgwZDgwOWVhMiwgMHgzOThmZWI3YyxcbiAgICAweDEzMmE0Zjk0LCAweDQzYjc5NTBlLCAweDJmZWU3ZDFjLCAweDIyMzYxM2JkLCAweGRkMDZjYWEyLCAweDM3ZGY5MzJiLCAweGM0MjQ4Mjg5LCAweGFjZjNlYmMzLFxuICAgIDB4NTcxNWY2YjcsIDB4ZWYzNDc4ZGQsIDB4ZjI2NzYxNmYsIDB4YzE0OGNiZTQsIDB4OTA1MjgxNWUsIDB4NWU0MTBmYWIsIDB4YjQ4YTI0NjUsIDB4MmVkYTdmYTQsXG4gICAgMHhlODdiNDBlNCwgMHhlOThlYTA4NCwgMHg1ODg5ZTllMSwgMHhlZmQzOTBmYywgMHhkZDA3ZDM1YiwgMHhkYjQ4NTY5NCwgMHgzOGQ3ZTViMiwgMHg1NzcyMDEwMSxcbiAgICAweDczMGVkZWJjLCAweDViNjQzMTEzLCAweDk0OTE3ZTRmLCAweDUwM2MyZmJhLCAweDY0NmYxMjgyLCAweDc1MjNkMjRhLCAweGUwNzc5Njk1LCAweGY5YzE3YThmLFxuICAgIDB4N2E1YjIxMjEsIDB4ZDE4N2I4OTYsIDB4MjkyNjNhNGQsIDB4YmE1MTBjZGYsIDB4ODFmNDdjOWYsIDB4YWQxMTYzZWQsIDB4ZWE3YjU5NjUsIDB4MWEwMDcyNmUsXG4gICAgMHgxMTQwMzA5MiwgMHgwMGRhNmQ3NywgMHg0YTBjZGQ2MSwgMHhhZDFmNDYwMywgMHg2MDViZGZiMCwgMHg5ZWVkYzM2NCwgMHgyMmViZTZhOCwgMHhjZWU3ZDI4YSxcbiAgICAweGEwZTczNmEwLCAweDU1NjRhNmI5LCAweDEwODUzMjA5LCAweGM3ZWI4ZjM3LCAweDJkZTcwNWNhLCAweDg5NTE1NzBmLCAweGRmMDk4MjJiLCAweGJkNjkxYTZjLFxuICAgIDB4YWExMmU0ZjIsIDB4ODc0NTFjMGYsIDB4ZTBmNmEyN2EsIDB4M2FkYTQ4MTksIDB4NGNmMTc2NGYsIDB4MGQ3NzFjMmIsIDB4NjdjZGIxNTYsIDB4MzUwZDgzODQsXG4gICAgMHg1OTM4ZmEwZiwgMHg0MjM5OWVmMywgMHgzNjk5N2IwNywgMHgwZTg0MDkzZCwgMHg0YWE5M2U2MSwgMHg4MzYwZDg3YiwgMHgxZmE5OGIwYywgMHgxMTQ5MzgyYyxcbiAgICAweGU5NzYyNWE1LCAweDA2MTRkMWI3LCAweDBlMjUyNDRiLCAweDBjNzY4MzQ3LCAweDU4OWU4ZDgyLCAweDBkMjA1OWQxLCAweGE0NjZiYjFlLCAweGY4ZGEwYTgyLFxuICAgIDB4MDRmMTkxMzAsIDB4YmE2ZTRlYzAsIDB4OTkyNjUxNjQsIDB4MWVlNzIzMGQsIDB4NTBiMmFkODAsIDB4ZWFlZTY4MDEsIDB4OGRiMmEyODMsIDB4ZWE4YmY1OWUpO1xuXG59O1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gY2FzdDUoa2V5KSB7XG4gIHRoaXMuY2FzdDUgPSBuZXcgb3BlbnBncF9zeW1lbmNfY2FzdDUoKTtcbiAgdGhpcy5jYXN0NS5zZXRLZXkodXRpbC5zdHIyYmluKGtleSkpO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FzdDUuZW5jcnlwdChibG9jayk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYXN0NTtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IGNhc3Q1LnByb3RvdHlwZS5ibG9ja1NpemUgPSA4O1xubW9kdWxlLmV4cG9ydHMua2V5U2l6ZSA9IGNhc3Q1LnByb3RvdHlwZS5rZXlTaXplID0gMTY7XG4iLCIvL1BhdWwgVGVybywgSnVseSAyMDAxXG4vL2h0dHA6Ly93d3cudGVyby5jby51ay9kZXMvXG4vL1xuLy9PcHRpbWlzZWQgZm9yIHBlcmZvcm1hbmNlIHdpdGggbGFyZ2UgYmxvY2tzIGJ5IE1pY2hhZWwgSGF5d29ydGgsIE5vdmVtYmVyIDIwMDFcbi8vaHR0cDovL3d3dy5uZXRkZWFsaW5nLmNvbVxuLy9cbi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuXG4vL1RISVMgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORFxuLy9BTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbi8vSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0Vcbi8vQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbi8vRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUxcbi8vREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFNcbi8vT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pXG4vL0hPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUXG4vL0xJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVlcbi8vT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRlxuLy9TVUNIIERBTUFHRS5cblxuLy9kZXNcbi8vdGhpcyB0YWtlcyB0aGUga2V5LCB0aGUgbWVzc2FnZSwgYW5kIHdoZXRoZXIgdG8gZW5jcnlwdCBvciBkZWNyeXB0XG5cbi8qKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvZGVzICovXG5cblxuXG5cbmZ1bmN0aW9uIGRlcyhrZXlzLCBtZXNzYWdlLCBlbmNyeXB0LCBtb2RlLCBpdiwgcGFkZGluZykge1xuICAvL2RlY2xhcmluZyB0aGlzIGxvY2FsbHkgc3BlZWRzIHRoaW5ncyB1cCBhIGJpdFxuICB2YXIgc3BmdW5jdGlvbjEgPSBuZXcgQXJyYXkoMHgxMDEwNDAwLCAwLCAweDEwMDAwLCAweDEwMTA0MDQsIDB4MTAxMDAwNCwgMHgxMDQwNCwgMHg0LCAweDEwMDAwLCAweDQwMCwgMHgxMDEwNDAwLFxuICAgIDB4MTAxMDQwNCwgMHg0MDAsIDB4MTAwMDQwNCwgMHgxMDEwMDA0LCAweDEwMDAwMDAsIDB4NCwgMHg0MDQsIDB4MTAwMDQwMCwgMHgxMDAwNDAwLCAweDEwNDAwLCAweDEwNDAwLCAweDEwMTAwMDAsXG4gICAgMHgxMDEwMDAwLCAweDEwMDA0MDQsIDB4MTAwMDQsIDB4MTAwMDAwNCwgMHgxMDAwMDA0LCAweDEwMDA0LCAwLCAweDQwNCwgMHgxMDQwNCwgMHgxMDAwMDAwLCAweDEwMDAwLCAweDEwMTA0MDQsIDB4NCxcbiAgICAweDEwMTAwMDAsIDB4MTAxMDQwMCwgMHgxMDAwMDAwLCAweDEwMDAwMDAsIDB4NDAwLCAweDEwMTAwMDQsIDB4MTAwMDAsIDB4MTA0MDAsIDB4MTAwMDAwNCwgMHg0MDAsIDB4NCwgMHgxMDAwNDA0LFxuICAgIDB4MTA0MDQsIDB4MTAxMDQwNCwgMHgxMDAwNCwgMHgxMDEwMDAwLCAweDEwMDA0MDQsIDB4MTAwMDAwNCwgMHg0MDQsIDB4MTA0MDQsIDB4MTAxMDQwMCwgMHg0MDQsIDB4MTAwMDQwMCxcbiAgICAweDEwMDA0MDAsIDAsIDB4MTAwMDQsIDB4MTA0MDAsIDAsIDB4MTAxMDAwNCk7XG4gIHZhciBzcGZ1bmN0aW9uMiA9IG5ldyBBcnJheSgtMHg3ZmVmN2ZlMCwgLTB4N2ZmZjgwMDAsIDB4ODAwMCwgMHgxMDgwMjAsIDB4MTAwMDAwLCAweDIwLCAtMHg3ZmVmZmZlMCwgLTB4N2ZmZjdmZTAsIC1cbiAgICAweDdmZmZmZmUwLCAtMHg3ZmVmN2ZlMCwgLTB4N2ZlZjgwMDAsIC0weDgwMDAwMDAwLCAtMHg3ZmZmODAwMCwgMHgxMDAwMDAsIDB4MjAsIC0weDdmZWZmZmUwLCAweDEwODAwMCwgMHgxMDAwMjAsIC1cbiAgICAweDdmZmY3ZmUwLCAwLCAtMHg4MDAwMDAwMCwgMHg4MDAwLCAweDEwODAyMCwgLTB4N2ZmMDAwMDAsIDB4MTAwMDIwLCAtMHg3ZmZmZmZlMCwgMCwgMHgxMDgwMDAsIDB4ODAyMCwgLTB4N2ZlZjgwMDAsIC1cbiAgICAweDdmZjAwMDAwLCAweDgwMjAsIDAsIDB4MTA4MDIwLCAtMHg3ZmVmZmZlMCwgMHgxMDAwMDAsIC0weDdmZmY3ZmUwLCAtMHg3ZmYwMDAwMCwgLTB4N2ZlZjgwMDAsIDB4ODAwMCwgLTB4N2ZmMDAwMDAsIC1cbiAgICAweDdmZmY4MDAwLCAweDIwLCAtMHg3ZmVmN2ZlMCwgMHgxMDgwMjAsIDB4MjAsIDB4ODAwMCwgLTB4ODAwMDAwMDAsIDB4ODAyMCwgLTB4N2ZlZjgwMDAsIDB4MTAwMDAwLCAtMHg3ZmZmZmZlMCxcbiAgICAweDEwMDAyMCwgLTB4N2ZmZjdmZTAsIC0weDdmZmZmZmUwLCAweDEwMDAyMCwgMHgxMDgwMDAsIDAsIC0weDdmZmY4MDAwLCAweDgwMjAsIC0weDgwMDAwMDAwLCAtMHg3ZmVmZmZlMCwgLVxuICAgIDB4N2ZlZjdmZTAsIDB4MTA4MDAwKTtcbiAgdmFyIHNwZnVuY3Rpb24zID0gbmV3IEFycmF5KDB4MjA4LCAweDgwMjAyMDAsIDAsIDB4ODAyMDAwOCwgMHg4MDAwMjAwLCAwLCAweDIwMjA4LCAweDgwMDAyMDAsIDB4MjAwMDgsIDB4ODAwMDAwOCxcbiAgICAweDgwMDAwMDgsIDB4MjAwMDAsIDB4ODAyMDIwOCwgMHgyMDAwOCwgMHg4MDIwMDAwLCAweDIwOCwgMHg4MDAwMDAwLCAweDgsIDB4ODAyMDIwMCwgMHgyMDAsIDB4MjAyMDAsIDB4ODAyMDAwMCxcbiAgICAweDgwMjAwMDgsIDB4MjAyMDgsIDB4ODAwMDIwOCwgMHgyMDIwMCwgMHgyMDAwMCwgMHg4MDAwMjA4LCAweDgsIDB4ODAyMDIwOCwgMHgyMDAsIDB4ODAwMDAwMCwgMHg4MDIwMjAwLCAweDgwMDAwMDAsXG4gICAgMHgyMDAwOCwgMHgyMDgsIDB4MjAwMDAsIDB4ODAyMDIwMCwgMHg4MDAwMjAwLCAwLCAweDIwMCwgMHgyMDAwOCwgMHg4MDIwMjA4LCAweDgwMDAyMDAsIDB4ODAwMDAwOCwgMHgyMDAsIDAsXG4gICAgMHg4MDIwMDA4LCAweDgwMDAyMDgsIDB4MjAwMDAsIDB4ODAwMDAwMCwgMHg4MDIwMjA4LCAweDgsIDB4MjAyMDgsIDB4MjAyMDAsIDB4ODAwMDAwOCwgMHg4MDIwMDAwLCAweDgwMDAyMDgsIDB4MjA4LFxuICAgIDB4ODAyMDAwMCwgMHgyMDIwOCwgMHg4LCAweDgwMjAwMDgsIDB4MjAyMDApO1xuICB2YXIgc3BmdW5jdGlvbjQgPSBuZXcgQXJyYXkoMHg4MDIwMDEsIDB4MjA4MSwgMHgyMDgxLCAweDgwLCAweDgwMjA4MCwgMHg4MDAwODEsIDB4ODAwMDAxLCAweDIwMDEsIDAsIDB4ODAyMDAwLFxuICAgIDB4ODAyMDAwLCAweDgwMjA4MSwgMHg4MSwgMCwgMHg4MDAwODAsIDB4ODAwMDAxLCAweDEsIDB4MjAwMCwgMHg4MDAwMDAsIDB4ODAyMDAxLCAweDgwLCAweDgwMDAwMCwgMHgyMDAxLCAweDIwODAsXG4gICAgMHg4MDAwODEsIDB4MSwgMHgyMDgwLCAweDgwMDA4MCwgMHgyMDAwLCAweDgwMjA4MCwgMHg4MDIwODEsIDB4ODEsIDB4ODAwMDgwLCAweDgwMDAwMSwgMHg4MDIwMDAsIDB4ODAyMDgxLCAweDgxLCAwLFxuICAgIDAsIDB4ODAyMDAwLCAweDIwODAsIDB4ODAwMDgwLCAweDgwMDA4MSwgMHgxLCAweDgwMjAwMSwgMHgyMDgxLCAweDIwODEsIDB4ODAsIDB4ODAyMDgxLCAweDgxLCAweDEsIDB4MjAwMCwgMHg4MDAwMDEsXG4gICAgMHgyMDAxLCAweDgwMjA4MCwgMHg4MDAwODEsIDB4MjAwMSwgMHgyMDgwLCAweDgwMDAwMCwgMHg4MDIwMDEsIDB4ODAsIDB4ODAwMDAwLCAweDIwMDAsIDB4ODAyMDgwKTtcbiAgdmFyIHNwZnVuY3Rpb241ID0gbmV3IEFycmF5KDB4MTAwLCAweDIwODAxMDAsIDB4MjA4MDAwMCwgMHg0MjAwMDEwMCwgMHg4MDAwMCwgMHgxMDAsIDB4NDAwMDAwMDAsIDB4MjA4MDAwMCxcbiAgICAweDQwMDgwMTAwLCAweDgwMDAwLCAweDIwMDAxMDAsIDB4NDAwODAxMDAsIDB4NDIwMDAxMDAsIDB4NDIwODAwMDAsIDB4ODAxMDAsIDB4NDAwMDAwMDAsIDB4MjAwMDAwMCwgMHg0MDA4MDAwMCxcbiAgICAweDQwMDgwMDAwLCAwLCAweDQwMDAwMTAwLCAweDQyMDgwMTAwLCAweDQyMDgwMTAwLCAweDIwMDAxMDAsIDB4NDIwODAwMDAsIDB4NDAwMDAxMDAsIDAsIDB4NDIwMDAwMDAsIDB4MjA4MDEwMCxcbiAgICAweDIwMDAwMDAsIDB4NDIwMDAwMDAsIDB4ODAxMDAsIDB4ODAwMDAsIDB4NDIwMDAxMDAsIDB4MTAwLCAweDIwMDAwMDAsIDB4NDAwMDAwMDAsIDB4MjA4MDAwMCwgMHg0MjAwMDEwMCxcbiAgICAweDQwMDgwMTAwLCAweDIwMDAxMDAsIDB4NDAwMDAwMDAsIDB4NDIwODAwMDAsIDB4MjA4MDEwMCwgMHg0MDA4MDEwMCwgMHgxMDAsIDB4MjAwMDAwMCwgMHg0MjA4MDAwMCwgMHg0MjA4MDEwMCxcbiAgICAweDgwMTAwLCAweDQyMDAwMDAwLCAweDQyMDgwMTAwLCAweDIwODAwMDAsIDAsIDB4NDAwODAwMDAsIDB4NDIwMDAwMDAsIDB4ODAxMDAsIDB4MjAwMDEwMCwgMHg0MDAwMDEwMCwgMHg4MDAwMCwgMCxcbiAgICAweDQwMDgwMDAwLCAweDIwODAxMDAsIDB4NDAwMDAxMDApO1xuICB2YXIgc3BmdW5jdGlvbjYgPSBuZXcgQXJyYXkoMHgyMDAwMDAxMCwgMHgyMDQwMDAwMCwgMHg0MDAwLCAweDIwNDA0MDEwLCAweDIwNDAwMDAwLCAweDEwLCAweDIwNDA0MDEwLCAweDQwMDAwMCxcbiAgICAweDIwMDA0MDAwLCAweDQwNDAxMCwgMHg0MDAwMDAsIDB4MjAwMDAwMTAsIDB4NDAwMDEwLCAweDIwMDA0MDAwLCAweDIwMDAwMDAwLCAweDQwMTAsIDAsIDB4NDAwMDEwLCAweDIwMDA0MDEwLFxuICAgIDB4NDAwMCwgMHg0MDQwMDAsIDB4MjAwMDQwMTAsIDB4MTAsIDB4MjA0MDAwMTAsIDB4MjA0MDAwMTAsIDAsIDB4NDA0MDEwLCAweDIwNDA0MDAwLCAweDQwMTAsIDB4NDA0MDAwLCAweDIwNDA0MDAwLFxuICAgIDB4MjAwMDAwMDAsIDB4MjAwMDQwMDAsIDB4MTAsIDB4MjA0MDAwMTAsIDB4NDA0MDAwLCAweDIwNDA0MDEwLCAweDQwMDAwMCwgMHg0MDEwLCAweDIwMDAwMDEwLCAweDQwMDAwMCwgMHgyMDAwNDAwMCxcbiAgICAweDIwMDAwMDAwLCAweDQwMTAsIDB4MjAwMDAwMTAsIDB4MjA0MDQwMTAsIDB4NDA0MDAwLCAweDIwNDAwMDAwLCAweDQwNDAxMCwgMHgyMDQwNDAwMCwgMCwgMHgyMDQwMDAxMCwgMHgxMCwgMHg0MDAwLFxuICAgIDB4MjA0MDAwMDAsIDB4NDA0MDEwLCAweDQwMDAsIDB4NDAwMDEwLCAweDIwMDA0MDEwLCAwLCAweDIwNDA0MDAwLCAweDIwMDAwMDAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCk7XG4gIHZhciBzcGZ1bmN0aW9uNyA9IG5ldyBBcnJheSgweDIwMDAwMCwgMHg0MjAwMDAyLCAweDQwMDA4MDIsIDAsIDB4ODAwLCAweDQwMDA4MDIsIDB4MjAwODAyLCAweDQyMDA4MDAsIDB4NDIwMDgwMixcbiAgICAweDIwMDAwMCwgMCwgMHg0MDAwMDAyLCAweDIsIDB4NDAwMDAwMCwgMHg0MjAwMDAyLCAweDgwMiwgMHg0MDAwODAwLCAweDIwMDgwMiwgMHgyMDAwMDIsIDB4NDAwMDgwMCwgMHg0MDAwMDAyLFxuICAgIDB4NDIwMDAwMCwgMHg0MjAwODAwLCAweDIwMDAwMiwgMHg0MjAwMDAwLCAweDgwMCwgMHg4MDIsIDB4NDIwMDgwMiwgMHgyMDA4MDAsIDB4MiwgMHg0MDAwMDAwLCAweDIwMDgwMCwgMHg0MDAwMDAwLFxuICAgIDB4MjAwODAwLCAweDIwMDAwMCwgMHg0MDAwODAyLCAweDQwMDA4MDIsIDB4NDIwMDAwMiwgMHg0MjAwMDAyLCAweDIsIDB4MjAwMDAyLCAweDQwMDAwMDAsIDB4NDAwMDgwMCwgMHgyMDAwMDAsXG4gICAgMHg0MjAwODAwLCAweDgwMiwgMHgyMDA4MDIsIDB4NDIwMDgwMCwgMHg4MDIsIDB4NDAwMDAwMiwgMHg0MjAwODAyLCAweDQyMDAwMDAsIDB4MjAwODAwLCAwLCAweDIsIDB4NDIwMDgwMiwgMCxcbiAgICAweDIwMDgwMiwgMHg0MjAwMDAwLCAweDgwMCwgMHg0MDAwMDAyLCAweDQwMDA4MDAsIDB4ODAwLCAweDIwMDAwMik7XG4gIHZhciBzcGZ1bmN0aW9uOCA9IG5ldyBBcnJheSgweDEwMDAxMDQwLCAweDEwMDAsIDB4NDAwMDAsIDB4MTAwNDEwNDAsIDB4MTAwMDAwMDAsIDB4MTAwMDEwNDAsIDB4NDAsIDB4MTAwMDAwMDAsXG4gICAgMHg0MDA0MCwgMHgxMDA0MDAwMCwgMHgxMDA0MTA0MCwgMHg0MTAwMCwgMHgxMDA0MTAwMCwgMHg0MTA0MCwgMHgxMDAwLCAweDQwLCAweDEwMDQwMDAwLCAweDEwMDAwMDQwLCAweDEwMDAxMDAwLFxuICAgIDB4MTA0MCwgMHg0MTAwMCwgMHg0MDA0MCwgMHgxMDA0MDA0MCwgMHgxMDA0MTAwMCwgMHgxMDQwLCAwLCAwLCAweDEwMDQwMDQwLCAweDEwMDAwMDQwLCAweDEwMDAxMDAwLCAweDQxMDQwLFxuICAgIDB4NDAwMDAsIDB4NDEwNDAsIDB4NDAwMDAsIDB4MTAwNDEwMDAsIDB4MTAwMCwgMHg0MCwgMHgxMDA0MDA0MCwgMHgxMDAwLCAweDQxMDQwLCAweDEwMDAxMDAwLCAweDQwLCAweDEwMDAwMDQwLFxuICAgIDB4MTAwNDAwMDAsIDB4MTAwNDAwNDAsIDB4MTAwMDAwMDAsIDB4NDAwMDAsIDB4MTAwMDEwNDAsIDAsIDB4MTAwNDEwNDAsIDB4NDAwNDAsIDB4MTAwMDAwNDAsIDB4MTAwNDAwMDAsIDB4MTAwMDEwMDAsXG4gICAgMHgxMDAwMTA0MCwgMCwgMHgxMDA0MTA0MCwgMHg0MTAwMCwgMHg0MTAwMCwgMHgxMDQwLCAweDEwNDAsIDB4NDAwNDAsIDB4MTAwMDAwMDAsIDB4MTAwNDEwMDApO1xuXG4gIC8vY3JlYXRlIHRoZSAxNiBvciA0OCBzdWJrZXlzIHdlIHdpbGwgbmVlZFxuICB2YXIgbSA9IDAsXG4gICAgaSwgaiwgdGVtcCwgdGVtcDIsIHJpZ2h0MSwgcmlnaHQyLCBsZWZ0LCByaWdodCwgbG9vcGluZztcbiAgdmFyIGNiY2xlZnQsIGNiY2xlZnQyLCBjYmNyaWdodCwgY2JjcmlnaHQyXG4gIHZhciBlbmRsb29wLCBsb29waW5jO1xuICB2YXIgbGVuID0gbWVzc2FnZS5sZW5ndGg7XG4gIHZhciBjaHVuayA9IDA7XG4gIC8vc2V0IHVwIHRoZSBsb29wcyBmb3Igc2luZ2xlIGFuZCB0cmlwbGUgZGVzXG4gIHZhciBpdGVyYXRpb25zID0ga2V5cy5sZW5ndGggPT0gMzIgPyAzIDogOTsgLy9zaW5nbGUgb3IgdHJpcGxlIGRlc1xuICBpZiAoaXRlcmF0aW9ucyA9PSAzKSB7XG4gICAgbG9vcGluZyA9IGVuY3J5cHQgPyBuZXcgQXJyYXkoMCwgMzIsIDIpIDogbmV3IEFycmF5KDMwLCAtMiwgLTIpO1xuICB9IGVsc2Uge1xuICAgIGxvb3BpbmcgPSBlbmNyeXB0ID8gbmV3IEFycmF5KDAsIDMyLCAyLCA2MiwgMzAsIC0yLCA2NCwgOTYsIDIpIDogbmV3IEFycmF5KDk0LCA2MiwgLTIsIDMyLCA2NCwgMiwgMzAsIC0yLCAtMik7XG4gIH1cblxuICAvL3BhZCB0aGUgbWVzc2FnZSBkZXBlbmRpbmcgb24gdGhlIHBhZGRpbmcgcGFyYW1ldGVyXG4gIC8vb25seSBhZGQgcGFkZGluZyBpZiBlbmNyeXB0aW5nIC0gbm90ZSB0aGF0IHlvdSBuZWVkIHRvIHVzZSB0aGUgc2FtZSBwYWRkaW5nIG9wdGlvbiBmb3IgYm90aCBlbmNyeXB0IGFuZCBkZWNyeXB0XG4gIGlmIChlbmNyeXB0KSB7XG4gICAgbWVzc2FnZSA9IGRlc19hZGRQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpO1xuICAgIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xuICB9XG5cbiAgLy9zdG9yZSB0aGUgcmVzdWx0IGhlcmVcbiAgcmVzdWx0ID0gXCJcIjtcbiAgdGVtcHJlc3VsdCA9IFwiXCI7XG5cbiAgaWYgKG1vZGUgPT0gMSkgeyAvL0NCQyBtb2RlXG4gICAgY2JjbGVmdCA9IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgaXYuY2hhckNvZGVBdChtKyspO1xuICAgIGNiY3JpZ2h0ID0gKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBpdi5jaGFyQ29kZUF0KG0rKyk7XG4gICAgbSA9IDA7XG4gIH1cblxuICAvL2xvb3AgdGhyb3VnaCBlYWNoIDY0IGJpdCBjaHVuayBvZiB0aGUgbWVzc2FnZVxuICB3aGlsZSAobSA8IGxlbikge1xuICAgIGxlZnQgPSAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IG1lc3NhZ2VcbiAgICAgIC5jaGFyQ29kZUF0KG0rKyk7XG4gICAgcmlnaHQgPSAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8XG4gICAgICBtZXNzYWdlLmNoYXJDb2RlQXQobSsrKTtcblxuICAgIC8vZm9yIENpcGhlciBCbG9jayBDaGFpbmluZyBtb2RlLCB4b3IgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgcHJldmlvdXMgcmVzdWx0XG4gICAgaWYgKG1vZGUgPT0gMSkge1xuICAgICAgaWYgKGVuY3J5cHQpIHtcbiAgICAgICAgbGVmdCBePSBjYmNsZWZ0O1xuICAgICAgICByaWdodCBePSBjYmNyaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNiY2xlZnQyID0gY2JjbGVmdDtcbiAgICAgICAgY2JjcmlnaHQyID0gY2JjcmlnaHQ7XG4gICAgICAgIGNiY2xlZnQgPSBsZWZ0O1xuICAgICAgICBjYmNyaWdodCA9IHJpZ2h0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vZmlyc3QgZWFjaCA2NCBidXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgbXVzdCBiZSBwZXJtdXRlZCBhY2NvcmRpbmcgdG8gSVBcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDQpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDE2KTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gMikgXiBsZWZ0KSAmIDB4MzMzMzMzMzM7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDIpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcblxuICAgIGxlZnQgPSAoKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMzEpKTtcbiAgICByaWdodCA9ICgocmlnaHQgPDwgMSkgfCAocmlnaHQgPj4+IDMxKSk7XG5cbiAgICAvL2RvIHRoaXMgZWl0aGVyIDEgb3IgMyB0aW1lcyBmb3IgZWFjaCBjaHVuayBvZiB0aGUgbWVzc2FnZVxuICAgIGZvciAoaiA9IDA7IGogPCBpdGVyYXRpb25zOyBqICs9IDMpIHtcbiAgICAgIGVuZGxvb3AgPSBsb29waW5nW2ogKyAxXTtcbiAgICAgIGxvb3BpbmMgPSBsb29waW5nW2ogKyAyXTtcbiAgICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiAgXG4gICAgICBmb3IgKGkgPSBsb29waW5nW2pdOyBpICE9IGVuZGxvb3A7IGkgKz0gbG9vcGluYykgeyAvL2ZvciBlZmZpY2llbmN5XG4gICAgICAgIHJpZ2h0MSA9IHJpZ2h0IF4ga2V5c1tpXTtcbiAgICAgICAgcmlnaHQyID0gKChyaWdodCA+Pj4gNCkgfCAocmlnaHQgPDwgMjgpKSBeIGtleXNbaSArIDFdO1xuICAgICAgICAvL3RoZSByZXN1bHQgaXMgYXR0YWluZWQgYnkgcGFzc2luZyB0aGVzZSBieXRlcyB0aHJvdWdoIHRoZSBTIHNlbGVjdGlvbiBmdW5jdGlvbnNcbiAgICAgICAgdGVtcCA9IGxlZnQ7XG4gICAgICAgIGxlZnQgPSByaWdodDtcbiAgICAgICAgcmlnaHQgPSB0ZW1wIF4gKHNwZnVuY3Rpb24yWyhyaWdodDEgPj4+IDI0KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjRbKHJpZ2h0MSA+Pj4gMTYpICYgMHgzZl0gfCBzcGZ1bmN0aW9uNlsocmlnaHQxID4+PlxuICAgICAgICAgIDgpICYgMHgzZl0gfCBzcGZ1bmN0aW9uOFtyaWdodDEgJiAweDNmXSB8IHNwZnVuY3Rpb24xWyhyaWdodDIgPj4+IDI0KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjNbKHJpZ2h0MiA+Pj4gMTYpICZcbiAgICAgICAgICAweDNmXSB8IHNwZnVuY3Rpb241WyhyaWdodDIgPj4+IDgpICYgMHgzZl0gfCBzcGZ1bmN0aW9uN1tyaWdodDIgJiAweDNmXSk7XG4gICAgICB9XG4gICAgICB0ZW1wID0gbGVmdDtcbiAgICAgIGxlZnQgPSByaWdodDtcbiAgICAgIHJpZ2h0ID0gdGVtcDsgLy91bnJldmVyc2UgbGVmdCBhbmQgcmlnaHRcbiAgICB9IC8vZm9yIGVpdGhlciAxIG9yIDMgaXRlcmF0aW9uc1xuXG4gICAgLy9tb3ZlIHRoZW4gZWFjaCBvbmUgYml0IHRvIHRoZSByaWdodFxuICAgIGxlZnQgPSAoKGxlZnQgPj4+IDEpIHwgKGxlZnQgPDwgMzEpKTtcbiAgICByaWdodCA9ICgocmlnaHQgPj4+IDEpIHwgKHJpZ2h0IDw8IDMxKSk7XG5cbiAgICAvL25vdyBwZXJmb3JtIElQLTEsIHdoaWNoIGlzIElQIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb25cbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxNikgXiByaWdodCkgJiAweDAwMDBmZmZmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxNik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCA0KTtcblxuICAgIC8vZm9yIENpcGhlciBCbG9jayBDaGFpbmluZyBtb2RlLCB4b3IgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgcHJldmlvdXMgcmVzdWx0XG4gICAgaWYgKG1vZGUgPT0gMSkge1xuICAgICAgaWYgKGVuY3J5cHQpIHtcbiAgICAgICAgY2JjbGVmdCA9IGxlZnQ7XG4gICAgICAgIGNiY3JpZ2h0ID0gcmlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0IF49IGNiY2xlZnQyO1xuICAgICAgICByaWdodCBePSBjYmNyaWdodDI7XG4gICAgICB9XG4gICAgfVxuICAgIHRlbXByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobGVmdCA+Pj4gMjQpLCAoKGxlZnQgPj4+IDE2KSAmIDB4ZmYpLCAoKGxlZnQgPj4+IDgpICYgMHhmZiksIChsZWZ0ICYgMHhmZiksIChcbiAgICAgIHJpZ2h0ID4+PiAyNCksICgocmlnaHQgPj4+IDE2KSAmIDB4ZmYpLCAoKHJpZ2h0ID4+PiA4KSAmIDB4ZmYpLCAocmlnaHQgJiAweGZmKSk7XG5cbiAgICBjaHVuayArPSA4O1xuICAgIGlmIChjaHVuayA9PSA1MTIpIHtcbiAgICAgIHJlc3VsdCArPSB0ZW1wcmVzdWx0O1xuICAgICAgdGVtcHJlc3VsdCA9IFwiXCI7XG4gICAgICBjaHVuayA9IDA7XG4gICAgfVxuICB9IC8vZm9yIGV2ZXJ5IDggY2hhcmFjdGVycywgb3IgNjQgYml0cyBpbiB0aGUgbWVzc2FnZVxuXG4gIC8vcmV0dXJuIHRoZSByZXN1bHQgYXMgYW4gYXJyYXlcbiAgcmVzdWx0ICs9IHRlbXByZXN1bHQ7XG5cbiAgLy9vbmx5IHJlbW92ZSBwYWRkaW5nIGlmIGRlY3J5cHRpbmcgLSBub3RlIHRoYXQgeW91IG5lZWQgdG8gdXNlIHRoZSBzYW1lIHBhZGRpbmcgb3B0aW9uIGZvciBib3RoIGVuY3J5cHQgYW5kIGRlY3J5cHRcbiAgaWYgKCFlbmNyeXB0KSB7XG4gICAgcmVzdWx0ID0gZGVzX3JlbW92ZVBhZGRpbmcocmVzdWx0LCBwYWRkaW5nKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59IC8vZW5kIG9mIGRlc1xuXG5cblxuLy9kZXNfY3JlYXRlS2V5c1xuLy90aGlzIHRha2VzIGFzIGlucHV0IGEgNjQgYml0IGtleSAoZXZlbiB0aG91Z2ggb25seSA1NiBiaXRzIGFyZSB1c2VkKVxuLy9hcyBhbiBhcnJheSBvZiAyIGludGVnZXJzLCBhbmQgcmV0dXJucyAxNiA0OCBiaXQga2V5c1xuXG5mdW5jdGlvbiBkZXNfY3JlYXRlS2V5cyhrZXkpIHtcbiAgLy9kZWNsYXJpbmcgdGhpcyBsb2NhbGx5IHNwZWVkcyB0aGluZ3MgdXAgYSBiaXRcbiAgcGMyYnl0ZXMwID0gbmV3IEFycmF5KDAsIDB4NCwgMHgyMDAwMDAwMCwgMHgyMDAwMDAwNCwgMHgxMDAwMCwgMHgxMDAwNCwgMHgyMDAxMDAwMCwgMHgyMDAxMDAwNCwgMHgyMDAsIDB4MjA0LFxuICAgIDB4MjAwMDAyMDAsIDB4MjAwMDAyMDQsIDB4MTAyMDAsIDB4MTAyMDQsIDB4MjAwMTAyMDAsIDB4MjAwMTAyMDQpO1xuICBwYzJieXRlczEgPSBuZXcgQXJyYXkoMCwgMHgxLCAweDEwMDAwMCwgMHgxMDAwMDEsIDB4NDAwMDAwMCwgMHg0MDAwMDAxLCAweDQxMDAwMDAsIDB4NDEwMDAwMSwgMHgxMDAsIDB4MTAxLCAweDEwMDEwMCxcbiAgICAweDEwMDEwMSwgMHg0MDAwMTAwLCAweDQwMDAxMDEsIDB4NDEwMDEwMCwgMHg0MTAwMTAxKTtcbiAgcGMyYnl0ZXMyID0gbmV3IEFycmF5KDAsIDB4OCwgMHg4MDAsIDB4ODA4LCAweDEwMDAwMDAsIDB4MTAwMDAwOCwgMHgxMDAwODAwLCAweDEwMDA4MDgsIDAsIDB4OCwgMHg4MDAsIDB4ODA4LFxuICAgIDB4MTAwMDAwMCwgMHgxMDAwMDA4LCAweDEwMDA4MDAsIDB4MTAwMDgwOCk7XG4gIHBjMmJ5dGVzMyA9IG5ldyBBcnJheSgwLCAweDIwMDAwMCwgMHg4MDAwMDAwLCAweDgyMDAwMDAsIDB4MjAwMCwgMHgyMDIwMDAsIDB4ODAwMjAwMCwgMHg4MjAyMDAwLCAweDIwMDAwLCAweDIyMDAwMCxcbiAgICAweDgwMjAwMDAsIDB4ODIyMDAwMCwgMHgyMjAwMCwgMHgyMjIwMDAsIDB4ODAyMjAwMCwgMHg4MjIyMDAwKTtcbiAgcGMyYnl0ZXM0ID0gbmV3IEFycmF5KDAsIDB4NDAwMDAsIDB4MTAsIDB4NDAwMTAsIDAsIDB4NDAwMDAsIDB4MTAsIDB4NDAwMTAsIDB4MTAwMCwgMHg0MTAwMCwgMHgxMDEwLCAweDQxMDEwLCAweDEwMDAsXG4gICAgMHg0MTAwMCwgMHgxMDEwLCAweDQxMDEwKTtcbiAgcGMyYnl0ZXM1ID0gbmV3IEFycmF5KDAsIDB4NDAwLCAweDIwLCAweDQyMCwgMCwgMHg0MDAsIDB4MjAsIDB4NDIwLCAweDIwMDAwMDAsIDB4MjAwMDQwMCwgMHgyMDAwMDIwLCAweDIwMDA0MjAsXG4gICAgMHgyMDAwMDAwLCAweDIwMDA0MDAsIDB4MjAwMDAyMCwgMHgyMDAwNDIwKTtcbiAgcGMyYnl0ZXM2ID0gbmV3IEFycmF5KDAsIDB4MTAwMDAwMDAsIDB4ODAwMDAsIDB4MTAwODAwMDAsIDB4MiwgMHgxMDAwMDAwMiwgMHg4MDAwMiwgMHgxMDA4MDAwMiwgMCwgMHgxMDAwMDAwMCxcbiAgICAweDgwMDAwLCAweDEwMDgwMDAwLCAweDIsIDB4MTAwMDAwMDIsIDB4ODAwMDIsIDB4MTAwODAwMDIpO1xuICBwYzJieXRlczcgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMCwgMHg4MDAsIDB4MTA4MDAsIDB4MjAwMDAwMDAsIDB4MjAwMTAwMDAsIDB4MjAwMDA4MDAsIDB4MjAwMTA4MDAsIDB4MjAwMDAsIDB4MzAwMDAsXG4gICAgMHgyMDgwMCwgMHgzMDgwMCwgMHgyMDAyMDAwMCwgMHgyMDAzMDAwMCwgMHgyMDAyMDgwMCwgMHgyMDAzMDgwMCk7XG4gIHBjMmJ5dGVzOCA9IG5ldyBBcnJheSgwLCAweDQwMDAwLCAwLCAweDQwMDAwLCAweDIsIDB4NDAwMDIsIDB4MiwgMHg0MDAwMiwgMHgyMDAwMDAwLCAweDIwNDAwMDAsIDB4MjAwMDAwMCwgMHgyMDQwMDAwLFxuICAgIDB4MjAwMDAwMiwgMHgyMDQwMDAyLCAweDIwMDAwMDIsIDB4MjA0MDAwMik7XG4gIHBjMmJ5dGVzOSA9IG5ldyBBcnJheSgwLCAweDEwMDAwMDAwLCAweDgsIDB4MTAwMDAwMDgsIDAsIDB4MTAwMDAwMDAsIDB4OCwgMHgxMDAwMDAwOCwgMHg0MDAsIDB4MTAwMDA0MDAsIDB4NDA4LFxuICAgIDB4MTAwMDA0MDgsIDB4NDAwLCAweDEwMDAwNDAwLCAweDQwOCwgMHgxMDAwMDQwOCk7XG4gIHBjMmJ5dGVzMTAgPSBuZXcgQXJyYXkoMCwgMHgyMCwgMCwgMHgyMCwgMHgxMDAwMDAsIDB4MTAwMDIwLCAweDEwMDAwMCwgMHgxMDAwMjAsIDB4MjAwMCwgMHgyMDIwLCAweDIwMDAsIDB4MjAyMCxcbiAgICAweDEwMjAwMCwgMHgxMDIwMjAsIDB4MTAyMDAwLCAweDEwMjAyMCk7XG4gIHBjMmJ5dGVzMTEgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMDAwLCAweDIwMCwgMHgxMDAwMjAwLCAweDIwMDAwMCwgMHgxMjAwMDAwLCAweDIwMDIwMCwgMHgxMjAwMjAwLCAweDQwMDAwMDAsIDB4NTAwMDAwMCxcbiAgICAweDQwMDAyMDAsIDB4NTAwMDIwMCwgMHg0MjAwMDAwLCAweDUyMDAwMDAsIDB4NDIwMDIwMCwgMHg1MjAwMjAwKTtcbiAgcGMyYnl0ZXMxMiA9IG5ldyBBcnJheSgwLCAweDEwMDAsIDB4ODAwMDAwMCwgMHg4MDAxMDAwLCAweDgwMDAwLCAweDgxMDAwLCAweDgwODAwMDAsIDB4ODA4MTAwMCwgMHgxMCwgMHgxMDEwLFxuICAgIDB4ODAwMDAxMCwgMHg4MDAxMDEwLCAweDgwMDEwLCAweDgxMDEwLCAweDgwODAwMTAsIDB4ODA4MTAxMCk7XG4gIHBjMmJ5dGVzMTMgPSBuZXcgQXJyYXkoMCwgMHg0LCAweDEwMCwgMHgxMDQsIDAsIDB4NCwgMHgxMDAsIDB4MTA0LCAweDEsIDB4NSwgMHgxMDEsIDB4MTA1LCAweDEsIDB4NSwgMHgxMDEsIDB4MTA1KTtcblxuICAvL2hvdyBtYW55IGl0ZXJhdGlvbnMgKDEgZm9yIGRlcywgMyBmb3IgdHJpcGxlIGRlcylcbiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoID4gOCA/IDMgOiAxOyAvL2NoYW5nZWQgYnkgUGF1bCAxNi82LzIwMDcgdG8gdXNlIFRyaXBsZSBERVMgZm9yIDkrIGJ5dGUga2V5c1xuICAvL3N0b3JlcyB0aGUgcmV0dXJuIGtleXNcbiAgdmFyIGtleXMgPSBuZXcgQXJyYXkoMzIgKiBpdGVyYXRpb25zKTtcbiAgLy9ub3cgZGVmaW5lIHRoZSBsZWZ0IHNoaWZ0cyB3aGljaCBuZWVkIHRvIGJlIGRvbmVcbiAgdmFyIHNoaWZ0cyA9IG5ldyBBcnJheSgwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAwKTtcbiAgLy9vdGhlciB2YXJpYWJsZXNcbiAgdmFyIGxlZnR0ZW1wLCByaWdodHRlbXAsIG0gPSAwLFxuICAgIG4gPSAwLFxuICAgIHRlbXA7XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCBpdGVyYXRpb25zOyBqKyspIHsgLy9laXRoZXIgMSBvciAzIGl0ZXJhdGlvbnNcbiAgICBsZWZ0ID0gKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBrZXkuY2hhckNvZGVBdChtKyspO1xuICAgIHJpZ2h0ID0gKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGtleS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBrZXkuY2hhckNvZGVBdChtKyspO1xuXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCA0KTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gLTE2KSBeIGxlZnQpICYgMHgwMDAwZmZmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAyKSBeIHJpZ2h0KSAmIDB4MzMzMzMzMzM7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDIpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAtMTYpIF4gbGVmdCkgJiAweDAwMDBmZmZmO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAtMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCA4KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuXG4gICAgLy90aGUgcmlnaHQgc2lkZSBuZWVkcyB0byBiZSBzaGlmdGVkIGFuZCB0byBnZXQgdGhlIGxhc3QgZm91ciBiaXRzIG9mIHRoZSBsZWZ0IHNpZGVcbiAgICB0ZW1wID0gKGxlZnQgPDwgOCkgfCAoKHJpZ2h0ID4+PiAyMCkgJiAweDAwMDAwMGYwKTtcbiAgICAvL2xlZnQgbmVlZHMgdG8gYmUgcHV0IHVwc2lkZSBkb3duXG4gICAgbGVmdCA9IChyaWdodCA8PCAyNCkgfCAoKHJpZ2h0IDw8IDgpICYgMHhmZjAwMDApIHwgKChyaWdodCA+Pj4gOCkgJiAweGZmMDApIHwgKChyaWdodCA+Pj4gMjQpICYgMHhmMCk7XG4gICAgcmlnaHQgPSB0ZW1wO1xuXG4gICAgLy9ub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGVzZSBzaGlmdHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGtleXNcbiAgICBmb3IgKGkgPSAwOyBpIDwgc2hpZnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvL3NoaWZ0IHRoZSBrZXlzIGVpdGhlciBvbmUgb3IgdHdvIGJpdHMgdG8gdGhlIGxlZnRcbiAgICAgIGlmIChzaGlmdHNbaV0pIHtcbiAgICAgICAgbGVmdCA9IChsZWZ0IDw8IDIpIHwgKGxlZnQgPj4+IDI2KTtcbiAgICAgICAgcmlnaHQgPSAocmlnaHQgPDwgMikgfCAocmlnaHQgPj4+IDI2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlZnQgPSAobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAyNyk7XG4gICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAyNyk7XG4gICAgICB9XG4gICAgICBsZWZ0ICY9IC0weGY7XG4gICAgICByaWdodCAmPSAtMHhmO1xuXG4gICAgICAvL25vdyBhcHBseSBQQy0yLCBpbiBzdWNoIGEgd2F5IHRoYXQgRSBpcyBlYXNpZXIgd2hlbiBlbmNyeXB0aW5nIG9yIGRlY3J5cHRpbmdcbiAgICAgIC8vdGhpcyBjb252ZXJzaW9uIHdpbGwgbG9vayBsaWtlIFBDLTIgZXhjZXB0IG9ubHkgdGhlIGxhc3QgNiBiaXRzIG9mIGVhY2ggYnl0ZSBhcmUgdXNlZFxuICAgICAgLy9yYXRoZXIgdGhhbiA0OCBjb25zZWN1dGl2ZSBiaXRzIGFuZCB0aGUgb3JkZXIgb2YgbGluZXMgd2lsbCBiZSBhY2NvcmRpbmcgdG8gXG4gICAgICAvL2hvdyB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zIHdpbGwgYmUgYXBwbGllZDogUzIsIFM0LCBTNiwgUzgsIFMxLCBTMywgUzUsIFM3XG4gICAgICBsZWZ0dGVtcCA9IHBjMmJ5dGVzMFtsZWZ0ID4+PiAyOF0gfCBwYzJieXRlczFbKGxlZnQgPj4+IDI0KSAmIDB4Zl0gfCBwYzJieXRlczJbKGxlZnQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczNbKFxuICAgICAgICBsZWZ0ID4+PiAxNikgJiAweGZdIHwgcGMyYnl0ZXM0WyhsZWZ0ID4+PiAxMikgJiAweGZdIHwgcGMyYnl0ZXM1WyhsZWZ0ID4+PiA4KSAmIDB4Zl0gfCBwYzJieXRlczZbKGxlZnQgPj4+IDQpICZcbiAgICAgICAgMHhmXTtcbiAgICAgIHJpZ2h0dGVtcCA9IHBjMmJ5dGVzN1tyaWdodCA+Pj4gMjhdIHwgcGMyYnl0ZXM4WyhyaWdodCA+Pj4gMjQpICYgMHhmXSB8IHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfFxuICAgICAgICBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXSB8IHBjMmJ5dGVzMTFbKHJpZ2h0ID4+PiAxMikgJiAweGZdIHwgcGMyYnl0ZXMxMlsocmlnaHQgPj4+IDgpICYgMHhmXSB8XG4gICAgICAgIHBjMmJ5dGVzMTNbKHJpZ2h0ID4+PiA0KSAmIDB4Zl07XG4gICAgICB0ZW1wID0gKChyaWdodHRlbXAgPj4+IDE2KSBeIGxlZnR0ZW1wKSAmIDB4MDAwMGZmZmY7XG4gICAgICBrZXlzW24rK10gPSBsZWZ0dGVtcCBeIHRlbXA7XG4gICAgICBrZXlzW24rK10gPSByaWdodHRlbXAgXiAodGVtcCA8PCAxNik7XG4gICAgfVxuICB9IC8vZm9yIGVhY2ggaXRlcmF0aW9uc1xuICAvL3JldHVybiB0aGUga2V5cyB3ZSd2ZSBjcmVhdGVkXG4gIHJldHVybiBrZXlzO1xufSAvL2VuZCBvZiBkZXNfY3JlYXRlS2V5c1xuXG5cbmZ1bmN0aW9uIGRlc19hZGRQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpIHtcbiAgdmFyIHBhZExlbmd0aCA9IDggLSAobWVzc2FnZS5sZW5ndGggJSA4KTtcbiAgaWYgKChwYWRkaW5nID09IDIpICYmIChwYWRMZW5ndGggPCA4KSkgeyAvL3BhZCB0aGUgbWVzc2FnZSB3aXRoIHNwYWNlc1xuICAgIG1lc3NhZ2UgKz0gXCIgICAgICAgIFwiLnN1YnN0cigwLCBwYWRMZW5ndGgpO1xuICB9IGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkgeyAvL1BLQ1M3IHBhZGRpbmdcbiAgICBtZXNzYWdlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLFxuICAgICAgcGFkTGVuZ3RoKS5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcbiAgfSBlbHNlIGlmICghcGFkZGluZyAmJiAocGFkTGVuZ3RoIDwgOCkpIHsgLy9wYWQgdGhlIG1lc3NhZ2Ugb3V0IHdpdGggbnVsbCBieXRlc1xuICAgIG1lc3NhZ2UgKz0gXCJcXDBcXDBcXDBcXDBcXDBcXDBcXDBcXDBcIi5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcbiAgfVxuICByZXR1cm4gbWVzc2FnZTtcbn1cblxuZnVuY3Rpb24gZGVzX3JlbW92ZVBhZGRpbmcobWVzc2FnZSwgcGFkZGluZykge1xuICBpZiAocGFkZGluZyA9PSAyKSB7IC8vIHNwYWNlIHBhZGRlZFxuICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoLyAqJC9nLCBcIlwiKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09IDEpIHsgLy8gUEtDUzdcbiAgICB2YXIgcGFkQ291bnQgPSBtZXNzYWdlLmNoYXJDb2RlQXQobWVzc2FnZS5sZW5ndGggLSAxKTtcbiAgICBtZXNzYWdlID0gbWVzc2FnZS5zdWJzdHIoMCwgbWVzc2FnZS5sZW5ndGggLSBwYWRDb3VudCk7XG4gIH0gZWxzZSBpZiAoIXBhZGRpbmcpIHsgLy8gbnVsbCBwYWRkaW5nXG4gICAgbWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZSgvXFwwKiQvZywgXCJcIik7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2U7XG59XG5cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnNcblxuZnVuY3Rpb24gRGVzKGtleSkge1xuICB0aGlzLmtleSA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgdGhpcy5rZXkucHVzaChrZXkuc3Vic3RyKGkgKiA4LCA4KSk7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzJdKSxcbiAgICAgIGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVsxXSksXG4gICAgICBkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMF0pLFxuICAgICAgdXRpbC5iaW4yc3RyKGJsb2NrKSwgdHJ1ZSwgMCwgbnVsbCwgbnVsbCksXG4gICAgICBmYWxzZSwgMCwgbnVsbCwgbnVsbCksIHRydWUsIDAsIG51bGwsIG51bGwpKTtcbiAgfVxufVxuXG5EZXMua2V5U2l6ZSA9IERlcy5wcm90b3R5cGUua2V5U2l6ZSA9IDI0O1xuRGVzLmJsb2NrU2l6ZSA9IERlcy5wcm90b3R5cGUuYmxvY2tTaXplID0gODtcblxuLy8gVGhpcyBpcyBcIm9yaWdpbmFsXCIgREVTIC0gRGVzIGlzIGFjdHVhbGx5IFRyaXBsZSBERVMuXG4vLyBUaGlzIGlzIG9ubHkgZXhwb3J0ZWQgc28gd2UgY2FuIHVuaXQgdGVzdC5cblxuZnVuY3Rpb24gT3JpZ2luYWxEZXMoa2V5KSB7XG4gIHRoaXMua2V5ID0ga2V5O1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrLCBwYWRkaW5nKSB7XG4gICAgdmFyIGtleXMgPSBkZXNfY3JlYXRlS2V5cyh0aGlzLmtleSk7XG4gICAgcmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoa2V5cywgdXRpbC5iaW4yc3RyKGJsb2NrKSwgdHJ1ZSwgMCwgbnVsbCwgcGFkZGluZykpO1xuICB9XG5cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oYmxvY2ssIHBhZGRpbmcpIHtcbiAgICB2YXIga2V5cyA9IGRlc19jcmVhdGVLZXlzKHRoaXMua2V5KTtcbiAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhrZXlzLCB1dGlsLmJpbjJzdHIoYmxvY2spLCBmYWxzZSwgMCwgbnVsbCwgcGFkZGluZykpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkZXM6IERlcyxcbiAgb3JpZ2luYWxEZXM6IE9yaWdpbmFsRGVzXG59XG4iLCJ2YXIgZGVzTW9kdWxlID0gcmVxdWlyZSgnLi9kZXMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlczogZGVzTW9kdWxlWydkZXMnXSxcbiAgb3JpZ2luYWxEZXM6IGRlc01vZHVsZVsnb3JpZ2luYWxEZXMnXSxcbiAgY2FzdDU6IHJlcXVpcmUoJy4vY2FzdDUuanMnKSxcbiAgdHdvZmlzaDogcmVxdWlyZSgnLi90d29maXNoLmpzJyksXG4gIGJsb3dmaXNoOiByZXF1aXJlKCcuL2Jsb3dmaXNoLmpzJylcbn1cblxudmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gYWVzKSB7XG4gIG1vZHVsZS5leHBvcnRzWydhZXMnICsgaV0gPSBhZXNbaV07XG59XG4iLCIvKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggXG4gKiBcbiAqIENpcGhlci5qc1xuICogQSBibG9jay1jaXBoZXIgYWxnb3JpdGhtIGltcGxlbWVudGF0aW9uIG9uIEphdmFTY3JpcHRcbiAqIFNlZSBDaXBoZXIucmVhZG1lLnR4dCBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi5cbiAqXG4gKiBDb3B5cmlnaHQoYykgMjAwOSBBdHN1c2hpIE9rYSBbIGh0dHA6Ly9va2EubnUvIF1cbiAqIFRoaXMgc2NyaXB0IGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExHUExcbiAqXG4gKiBBQ0tOT1dMRURHTUVOVFxuICpcbiAqICAgICBUaGUgbWFpbiBzdWJyb3V0aW5lcyBhcmUgd3JpdHRlbiBieSBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuLlxuICogXG4gKiAgICAgTWljaGllbCB2YW4gRXZlcmRpbmdlblxuICogICAgIGh0dHA6Ly9ob21lLnZlcnNhdGVsLm5sL01BdmFuRXZlcmRpbmdlbi9pbmRleC5odG1sXG4gKiBcbiAqICAgICBBbGwgcmlnaHRzIGZvciB0aGVzZSByb3V0aW5lcyBhcmUgcmVzZXJ2ZWQgdG8gTWljaGllbCB2YW4gRXZlcmRpbmdlbi5cbiAqXG4gKi9cblxuLyoqIEBtb2R1bGUgY3J5cHRvL2NpcGhlci90d29maXNoICovXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vTWF0aFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBNQVhJTlQgPSAweEZGRkZGRkZGO1xuXG5mdW5jdGlvbiByb3RiKGIsIG4pIHtcbiAgcmV0dXJuIChiIDw8IG4gfCBiID4+PiAoOCAtIG4pKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIHJvdHcodywgbikge1xuICByZXR1cm4gKHcgPDwgbiB8IHcgPj4+ICgzMiAtIG4pKSAmIE1BWElOVDtcbn1cblxuZnVuY3Rpb24gZ2V0VyhhLCBpKSB7XG4gIHJldHVybiBhW2ldIHwgYVtpICsgMV0gPDwgOCB8IGFbaSArIDJdIDw8IDE2IHwgYVtpICsgM10gPDwgMjQ7XG59XG5cbmZ1bmN0aW9uIHNldFcoYSwgaSwgdykge1xuICBhLnNwbGljZShpLCA0LCB3ICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgKHcgPj4+IDE2KSAmIDB4RkYsICh3ID4+PiAyNCkgJiAweEZGKTtcbn1cblxuZnVuY3Rpb24gc2V0V0ludihhLCBpLCB3KSB7XG4gIGEuc3BsaWNlKGksIDQsICh3ID4+PiAyNCkgJiAweEZGLCAodyA+Pj4gMTYpICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgdyAmIDB4RkYpO1xufVxuXG5mdW5jdGlvbiBnZXRCKHgsIG4pIHtcbiAgcmV0dXJuICh4ID4+PiAobiAqIDgpKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIGdldE5yQml0cyhpKSB7XG4gIHZhciBuID0gMDtcbiAgd2hpbGUgKGkgPiAwKSB7XG4gICAgbisrO1xuICAgIGkgPj4+PSAxO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBnZXRNYXNrKG4pIHtcbiAgcmV0dXJuICgxIDw8IG4pIC0gMTtcbn1cblxuLy9hZGRlZCAyMDA4LzExLzEzIFhYWCBNVVNUIFVTRSBPTkUtV0FZIEhBU0ggRlVOQ1RJT04gRk9SIFNFQ1VSSVRZIFJFQVNPTlxuXG5mdW5jdGlvbiByYW5kQnl0ZSgpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDI1Nik7XG59XG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBUd29maXNoXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNyZWF0ZVR3b2Zpc2goKSB7XG4gIC8vXG4gIHZhciBrZXlCeXRlcyA9IG51bGw7XG4gIHZhciBkYXRhQnl0ZXMgPSBudWxsO1xuICB2YXIgZGF0YU9mZnNldCA9IC0xO1xuICAvLyB2YXIgZGF0YUxlbmd0aCA9IC0xO1xuICB2YXIgYWxnb3JpdGhtTmFtZSA9IG51bGw7XG4gIC8vIHZhciBpZHgyID0gLTE7XG4gIC8vXG5cbiAgYWxnb3JpdGhtTmFtZSA9IFwidHdvZmlzaFwiO1xuXG4gIHZhciB0ZnNLZXkgPSBbXTtcbiAgdmFyIHRmc00gPSBbXG4gICAgW10sXG4gICAgW10sXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBmdW5jdGlvbiB0ZnNJbml0KGtleSkge1xuICAgIGtleUJ5dGVzID0ga2V5O1xuICAgIHZhciBpLCBhLCBiLCBjLCBkLCBtZUtleSA9IFtdLFxuICAgICAgbW9LZXkgPSBbXSxcbiAgICAgIGluS2V5ID0gW107XG4gICAgdmFyIGtMZW47XG4gICAgdmFyIHNLZXkgPSBbXTtcbiAgICB2YXIgZjAxLCBmNWIsIGZlZjtcblxuICAgIHZhciBxMCA9IFtcbiAgICAgIFs4LCAxLCA3LCAxMywgNiwgMTUsIDMsIDIsIDAsIDExLCA1LCA5LCAxNCwgMTIsIDEwLCA0XSxcbiAgICAgIFsyLCA4LCAxMSwgMTMsIDE1LCA3LCA2LCAxNCwgMywgMSwgOSwgNCwgMCwgMTAsIDEyLCA1XVxuICAgIF07XG4gICAgdmFyIHExID0gW1xuICAgICAgWzE0LCAxMiwgMTEsIDgsIDEsIDIsIDMsIDUsIDE1LCA0LCAxMCwgNiwgNywgMCwgOSwgMTNdLFxuICAgICAgWzEsIDE0LCAyLCAxMSwgNCwgMTIsIDMsIDcsIDYsIDEzLCAxMCwgNSwgMTUsIDksIDAsIDhdXG4gICAgXTtcbiAgICB2YXIgcTIgPSBbXG4gICAgICBbMTEsIDEwLCA1LCAxNCwgNiwgMTMsIDksIDAsIDEyLCA4LCAxNSwgMywgMiwgNCwgNywgMV0sXG4gICAgICBbNCwgMTIsIDcsIDUsIDEsIDYsIDksIDEwLCAwLCAxNCwgMTMsIDgsIDIsIDExLCAzLCAxNV1cbiAgICBdO1xuICAgIHZhciBxMyA9IFtcbiAgICAgIFsxMywgNywgMTUsIDQsIDEsIDIsIDYsIDE0LCA5LCAxMSwgMywgMCwgOCwgNSwgMTIsIDEwXSxcbiAgICAgIFsxMSwgOSwgNSwgMSwgMTIsIDMsIDEzLCAxNCwgNiwgNCwgNywgMTUsIDIsIDAsIDgsIDEwXVxuICAgIF07XG4gICAgdmFyIHJvcjQgPSBbMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNV07XG4gICAgdmFyIGFzaHggPSBbMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLCA1LCAxNCwgN107XG4gICAgdmFyIHEgPSBbXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICB2YXIgbSA9IFtcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcblxuICAgIGZ1bmN0aW9uIGZmbTViKHgpIHtcbiAgICAgIHJldHVybiB4IF4gKHggPj4gMikgXiBbMCwgOTAsIDE4MCwgMjM4XVt4ICYgM107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmZtRWYoeCkge1xuICAgICAgcmV0dXJuIHggXiAoeCA+PiAxKSBeICh4ID4+IDIpIF4gWzAsIDIzOCwgMTgwLCA5MF1beCAmIDNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1kc1JlbShwLCBxKSB7XG4gICAgICB2YXIgaSwgdCwgdTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgdCA9IHEgPj4+IDI0O1xuICAgICAgICBxID0gKChxIDw8IDgpICYgTUFYSU5UKSB8IHAgPj4+IDI0O1xuICAgICAgICBwID0gKHAgPDwgOCkgJiBNQVhJTlQ7XG4gICAgICAgIHUgPSB0IDw8IDE7XG4gICAgICAgIGlmICh0ICYgMTI4KSB7XG4gICAgICAgICAgdSBePSAzMzM7XG4gICAgICAgIH1cbiAgICAgICAgcSBePSB0IF4gKHUgPDwgMTYpO1xuICAgICAgICB1IF49IHQgPj4+IDE7XG4gICAgICAgIGlmICh0ICYgMSkge1xuICAgICAgICAgIHUgXj0gMTY2O1xuICAgICAgICB9XG4gICAgICAgIHEgXj0gdSA8PCAyNCB8IHUgPDwgODtcbiAgICAgIH1cbiAgICAgIHJldHVybiBxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHFwKG4sIHgpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkO1xuICAgICAgYSA9IHggPj4gNDtcbiAgICAgIGIgPSB4ICYgMTU7XG4gICAgICBjID0gcTBbbl1bYSBeIGJdO1xuICAgICAgZCA9IHExW25dW3JvcjRbYl0gXiBhc2h4W2FdXTtcbiAgICAgIHJldHVybiBxM1tuXVtyb3I0W2RdIF4gYXNoeFtjXV0gPDwgNCB8IHEyW25dW2MgXiBkXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoRnVuKHgsIGtleSkge1xuICAgICAgdmFyIGEgPSBnZXRCKHgsIDApLFxuICAgICAgICBiID0gZ2V0Qih4LCAxKSxcbiAgICAgICAgYyA9IGdldEIoeCwgMiksXG4gICAgICAgIGQgPSBnZXRCKHgsIDMpO1xuICAgICAgc3dpdGNoIChrTGVuKSB7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoa2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoa2V5WzNdLCAxKTtcbiAgICAgICAgICBjID0gcVswXVtjXSBeIGdldEIoa2V5WzNdLCAyKTtcbiAgICAgICAgICBkID0gcVsxXVtkXSBeIGdldEIoa2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbMl0sIDApO1xuICAgICAgICAgIGIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihrZXlbMl0sIDMpO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgYSA9IHFbMF1bcVswXVthXSBeIGdldEIoa2V5WzFdLCAwKV0gXiBnZXRCKGtleVswXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bcVsxXVtiXSBeIGdldEIoa2V5WzFdLCAxKV0gXiBnZXRCKGtleVswXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMV1bcVswXVtjXSBeIGdldEIoa2V5WzFdLCAyKV0gXiBnZXRCKGtleVswXSwgMik7XG4gICAgICAgICAgZCA9IHFbMV1bcVsxXVtkXSBeIGdldEIoa2V5WzFdLCAzKV0gXiBnZXRCKGtleVswXSwgMyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbVswXVthXSBeIG1bMV1bYl0gXiBtWzJdW2NdIF4gbVszXVtkXTtcbiAgICB9XG5cbiAgICBrZXlCeXRlcyA9IGtleUJ5dGVzLnNsaWNlKDAsIDMyKTtcbiAgICBpID0ga2V5Qnl0ZXMubGVuZ3RoO1xuICAgIHdoaWxlIChpICE9IDE2ICYmIGkgIT0gMjQgJiYgaSAhPSAzMilcbiAgICAgIGtleUJ5dGVzW2krK10gPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGtleUJ5dGVzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICBpbktleVtpID4+IDJdID0gZ2V0VyhrZXlCeXRlcywgaSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgcVswXVtpXSA9IHFwKDAsIGkpO1xuICAgICAgcVsxXVtpXSA9IHFwKDEsIGkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIGYwMSA9IHFbMV1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMF1baV0gPSBmMDEgKyAoZjViIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIG1bMl1baV0gPSBmNWIgKyAoZmVmIDw8IDgpICsgKGYwMSA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIGYwMSA9IHFbMF1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMV1baV0gPSBmZWYgKyAoZmVmIDw8IDgpICsgKGY1YiA8PCAxNikgKyAoZjAxIDw8IDI0KTtcbiAgICAgIG1bM11baV0gPSBmNWIgKyAoZjAxIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZjViIDw8IDI0KTtcbiAgICB9XG5cbiAgICBrTGVuID0gaW5LZXkubGVuZ3RoIC8gMjtcbiAgICBmb3IgKGkgPSAwOyBpIDwga0xlbjsgaSsrKSB7XG4gICAgICBhID0gaW5LZXlbaSArIGldO1xuICAgICAgbWVLZXlbaV0gPSBhO1xuICAgICAgYiA9IGluS2V5W2kgKyBpICsgMV07XG4gICAgICBtb0tleVtpXSA9IGI7XG4gICAgICBzS2V5W2tMZW4gLSBpIC0gMV0gPSBtZHNSZW0oYSwgYik7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA0MDsgaSArPSAyKSB7XG4gICAgICBhID0gMHgxMDEwMTAxICogaTtcbiAgICAgIGIgPSBhICsgMHgxMDEwMTAxO1xuICAgICAgYSA9IGhGdW4oYSwgbWVLZXkpO1xuICAgICAgYiA9IHJvdHcoaEZ1bihiLCBtb0tleSksIDgpO1xuICAgICAgdGZzS2V5W2ldID0gKGEgKyBiKSAmIE1BWElOVDtcbiAgICAgIHRmc0tleVtpICsgMV0gPSByb3R3KGEgKyAyICogYiwgOSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgYSA9IGIgPSBjID0gZCA9IGk7XG4gICAgICBzd2l0Y2ggKGtMZW4pIHtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoc0tleVszXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbM10sIDIpO1xuICAgICAgICAgIGQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzJdLCAwKTtcbiAgICAgICAgICBiID0gcVsxXVtiXSBeIGdldEIoc0tleVsyXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihzS2V5WzJdLCAzKTtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHRmc01bMF1baV0gPSBtWzBdW3FbMF1bcVswXVthXSBeIGdldEIoc0tleVsxXSwgMCldIF4gZ2V0QihzS2V5WzBdLCAwKV07XG4gICAgICAgICAgdGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV0gXiBnZXRCKHNLZXlbMF0sIDEpXTtcbiAgICAgICAgICB0ZnNNWzJdW2ldID0gbVsyXVtxWzFdW3FbMF1bY10gXiBnZXRCKHNLZXlbMV0sIDIpXSBeIGdldEIoc0tleVswXSwgMildO1xuICAgICAgICAgIHRmc01bM11baV0gPSBtWzNdW3FbMV1bcVsxXVtkXSBeIGdldEIoc0tleVsxXSwgMyldIF4gZ2V0QihzS2V5WzBdLCAzKV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzAoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMCldIF4gdGZzTVsxXVtnZXRCKHgsIDEpXSBeIHRmc01bMl1bZ2V0Qih4LCAyKV0gXiB0ZnNNWzNdW2dldEIoeCwgMyldO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzEoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMyldIF4gdGZzTVsxXVtnZXRCKHgsIDApXSBeIHRmc01bMl1bZ2V0Qih4LCAxKV0gXiB0ZnNNWzNdW2dldEIoeCwgMildO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRnJuZChyLCBibGspIHtcbiAgICB2YXIgYSA9IHRmc0cwKGJsa1swXSk7XG4gICAgdmFyIGIgPSB0ZnNHMShibGtbMV0pO1xuICAgIGJsa1syXSA9IHJvdHcoYmxrWzJdIF4gKGEgKyBiICsgdGZzS2V5WzQgKiByICsgOF0pICYgTUFYSU5ULCAzMSk7XG4gICAgYmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBibGtbMV0gPSByb3R3KGJsa1sxXSwgMSkgXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiByICsgMTFdKSAmIE1BWElOVDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0lybmQoaSwgYmxrKSB7XG4gICAgdmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuICAgIHZhciBiID0gdGZzRzEoYmxrWzFdKTtcbiAgICBibGtbMl0gPSByb3R3KGJsa1syXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMF0pICYgTUFYSU5UO1xuICAgIGJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7XG4gICAgYmxrWzFdID0gcm90dyhibGtbMV0gXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiBpICsgOV0pICYgTUFYSU5ULCAzMSk7XG4gIH1cblxuICBmdW5jdGlvbiB0ZnNDbG9zZSgpIHtcbiAgICB0ZnNLZXkgPSBbXTtcbiAgICB0ZnNNID0gW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgICAgW11cbiAgICBdO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRW5jcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbMF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbMV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbMl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzNdXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykge1xuICAgICAgdGZzRnJuZChqLCBibGspO1xuICAgIH1cbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzRdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA4LCBibGtbMF0gXiB0ZnNLZXlbNl0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVs3XSk7XG4gICAgZGF0YU9mZnNldCArPSAxNjtcbiAgICByZXR1cm4gZGF0YUJ5dGVzO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRGVjcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbNF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbNV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbNl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzddXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHRmc0lybmQoaiwgYmxrKTtcbiAgICB9XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVswXSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzJdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbM10pO1xuICAgIGRhdGFPZmZzZXQgKz0gMTY7XG4gIH1cblxuICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbiAgZnVuY3Rpb24gdGZzRmluYWwoKSB7XG4gICAgcmV0dXJuIGRhdGFCeXRlcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ0d29maXNoXCIsXG4gICAgYmxvY2tzaXplOiAxMjggLyA4LFxuICAgIG9wZW46IHRmc0luaXQsXG4gICAgY2xvc2U6IHRmc0Nsb3NlLFxuICAgIGVuY3J5cHQ6IHRmc0VuY3J5cHQsXG4gICAgZGVjcnlwdDogdGZzRGVjcnlwdCxcbiAgICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG4gICAgZmluYWxpemU6IHRmc0ZpbmFsXG4gIH07XG59XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIFRGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBibG9ja19jb3B5ID0gW10uY29uY2F0KGJsb2NrKTtcbiAgdmFyIHRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0Zi5vcGVuKHV0aWwuc3RyMmJpbihrZXkpLCAwKTtcbiAgdmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7XG4gIHRmLmNsb3NlKCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIFRGKGtleSkge1xuICB0aGlzLnRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0aGlzLnRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksIDApO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMudGYuZW5jcnlwdChbXS5jb25jYXQoYmxvY2spLCAwKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gVEY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gVEYucHJvdG90eXBlLmtleVNpemUgPSAzMjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IFRGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxuLyoqIEBtb2R1bGUgY3J5cHRvL2NyeXB0byAqL1xuXG52YXIgcmFuZG9tID0gcmVxdWlyZSgnLi9yYW5kb20uanMnKSxcbiAgY2lwaGVyID0gcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBFbmNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAgICogYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHttb2R1bGU6dHlwZS9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gICAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IGlmIFJTQSBhbiBtb2R1bGU6dHlwZS9tcGk7IFxuICAgKiBpZiBlbGdhbWFsIGVuY3J5cHRpb24gYW4gYXJyYXkgb2YgdHdvIG1vZHVsZTp0eXBlL21waSBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIG51bGxcbiAgICovXG4gIHB1YmxpY0tleUVuY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIHB1YmxpY01QSXMsIGRhdGEpIHtcbiAgICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICAgICAgdmFyIG4gPSBwdWJsaWNNUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBlID0gcHVibGljTVBJc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIFtyc2EuZW5jcnlwdChtLCBlLCBuKV07XG5cbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgcCA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGcgPSBwdWJsaWNNUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciB5ID0gcHVibGljTVBJc1syXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIGVsZ2FtYWwuZW5jcnlwdChtLCBnLCBwLCB5KTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIG1waS5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgICByZXR1cm4gbXBpO1xuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBvZiB0aGUgcHJpdmF0ZSBrZXksXG4gICAqIHRoZSBzcGVjaWZpZWQgc2VjcmV0TVBJcyBvZiB0aGUgcHJpdmF0ZSBrZXkgYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIG9mIHRoZSBwdWJsaWMga2V5IHBhcnQgb2YgdGhlIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7QXJyYXk8bW9kdWxlOnR5cGUvbXBpPn0gc2VjcmV0TVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgdXNlZFxuICAgKiBAcGFyYW0ge21vZHVsZTp0eXBlL21waX0gZGF0YSBEYXRhIHRvIGJlIGVuY3J5cHRlZCBhcyBNUElcbiAgICogQHJldHVybiB7bW9kdWxlOnR5cGUvbXBpfSByZXR1cm5zIGEgYmlnIGludGVnZXIgY29udGFpbmluZyB0aGUgZGVjcnlwdGVkIGRhdGE7IG90aGVyd2lzZSBudWxsXG4gICAqL1xuXG4gIHB1YmxpY0tleURlY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIGtleUludGVnZXJzLCBkYXRhSW50ZWdlcnMpIHtcbiAgICB2YXIgYm4gPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICAvLyAwIGFuZCAxIGFyZSB0aGUgcHVibGljIGtleS5cbiAgICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHEgPSBrZXlJbnRlZ2Vyc1s0XS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgdSA9IGtleUludGVnZXJzWzVdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHJldHVybiByc2EuZGVjcnlwdChtLCBkLCBwLCBxLCB1KTtcbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgeCA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBjMSA9IGRhdGFJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgYzIgPSBkYXRhSW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gZWxnYW1hbC5kZWNyeXB0KGMxLCBjMiwgcCwgeCk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIHZhciByZXN1bHQgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICByZXN1bHQuZnJvbUJpZ0ludGVnZXIoYm4pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBwcml2YXRlIGtleSBvZiBhbiBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFsZ28gVGhlIHB1YmxpYyBrZXkgYWxnb3JpdGhtXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBudW1iZXIgb2YgaW50ZWdlcnMuXG4gICAqL1xuICBnZXRQcml2YXRlTXBpQ291bnQ6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIG11bHRpcHJlY2lzaW9uIGludGVnZXIgKE1QSSkgb2YgUlNBIHNlY3JldCBleHBvbmVudCBkLlxuICAgICAgICAvLyAgIC0gTVBJIG9mIFJTQSBzZWNyZXQgcHJpbWUgdmFsdWUgcC5cbiAgICAgICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHEgKHAgPCBxKS5cbiAgICAgICAgLy8gICAtIE1QSSBvZiB1LCB0aGUgbXVsdGlwbGljYXRpdmUgaW52ZXJzZSBvZiBwLCBtb2QgcS5cbiAgICAgICAgcmV0dXJuIDQ7XG4gICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRWxnYW1hbCBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIE1QSSBvZiBFbGdhbWFsIHNlY3JldCBleHBvbmVudCB4LlxuICAgICAgICByZXR1cm4gMTtcbiAgICAgIGNhc2UgJ2RzYSc6XG4gICAgICAgIC8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIE1QSSBvZiBEU0Egc2VjcmV0IGV4cG9uZW50IHguXG4gICAgICAgIHJldHVybiAxO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobScpO1xuICAgIH1cbiAgfSxcblxuICBnZXRQdWJsaWNNcGlDb3VudDogZnVuY3Rpb24oYWxnbykge1xuICAgIC8vIC0gQSBzZXJpZXMgb2YgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgY29tcHJpc2luZyB0aGUga2V5IG1hdGVyaWFsOlxuICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHB1YmxpYyBrZXlzOlxuICAgIC8vICAgICAgIC0gYSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBwdWJsaWMgbW9kdWx1cyBuO1xuICAgIC8vICAgICAgIC0gYW4gTVBJIG9mIFJTQSBwdWJsaWMgZW5jcnlwdGlvbiBleHBvbmVudCBlLlxuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICBjYXNlICdyc2Ffc2lnbic6XG4gICAgICAgIHJldHVybiAyO1xuXG4gICAgICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRWxnYW1hbCBwdWJsaWMga2V5czpcbiAgICAgICAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHJpbWUgcDtcbiAgICAgICAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgZ3JvdXAgZ2VuZXJhdG9yIGc7XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIHB1YmxpYyBrZXkgdmFsdWUgeSAoPSBnKip4IG1vZCBwIHdoZXJlIHggIGlzIHNlY3JldCkuXG4gICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgcmV0dXJuIDM7XG5cbiAgICAgICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0EgcHVibGljIGtleXM6XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBwcmltZSBwO1xuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgZ3JvdXAgb3JkZXIgcSAocSBpcyBhIHByaW1lIGRpdmlzb3Igb2YgcC0xKTtcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIGdlbmVyYXRvciBnO1xuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgcHVibGljLWtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS5cbiAgICAgIGNhc2UgJ2RzYSc6XG4gICAgICAgIHJldHVybiA0O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gYWxnb3JpdGhtLicpO1xuICAgIH1cbiAgfSxcblxuICBnZW5lcmF0ZU1waTogZnVuY3Rpb24oYWxnbywgYml0cykge1xuICAgIHZhciByZXN1bHQgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICAgIC8vcmVtZW1iZXIgXCJwdWJsaWNLZXlcIiByZWZlcnMgdG8gdGhlIGNyeXB0by9wdWJsaWNfa2V5IGRpclxuICAgICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICAgIHZhciBrZXlPYmplY3QgPSByc2EuZ2VuZXJhdGUoYml0cywgXCIxMDAwMVwiKTtcbiAgICAgICAgICB2YXIgb3V0cHV0ID0gW107XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0Lm4pO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5lZSk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LmQpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5wKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QucSk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LnUpO1xuICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBhbGdvcml0aG0gZm9yIGtleSBnZW5lcmF0aW9uLicpO1xuICAgICAgfVxuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lm1hcChmdW5jdGlvbihibikge1xuICAgICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgbXBpLmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgICAgIHJldHVybiBtcGk7XG4gICAgfSk7XG4gIH0sXG5cblxuICAvKipcbiAgICogZ2VuZXJhdGUgcmFuZG9tIGJ5dGUgcHJlZml4IGFzIHN0cmluZyBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMilcbiAgICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgd2l0aCBsZW5ndGggZXF1YWwgdG8gdGhlIGJsb2NrXG4gICAqIHNpemUgb2YgdGhlIGNpcGhlclxuICAgKi9cbiAgZ2V0UHJlZml4UmFuZG9tOiBmdW5jdGlvbihhbGdvKSB7XG4gICAgcmV0dXJuIHJhbmRvbS5nZXRSYW5kb21CeXRlcyhjaXBoZXJbYWxnb10uYmxvY2tTaXplKTtcbiAgfSxcblxuICAvKipcbiAgICogR2VuZXJhdGluZyBhIHNlc3Npb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHN5bW1ldHJpYyBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMilcbiAgICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIGtleVxuICAgKi9cbiAgZ2VuZXJhdGVTZXNzaW9uS2V5OiBmdW5jdGlvbihhbGdvKSB7XG4gICAgcmV0dXJuIHJhbmRvbS5nZXRSYW5kb21CeXRlcyhjaXBoZXJbYWxnb10ua2V5U2l6ZSk7XG4gIH0sXG5cbn07XG4iLCJ2YXIgc2hhID0gcmVxdWlyZSgnLi9zaGEuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG1kNTogcmVxdWlyZSgnLi9tZDUuanMnKSxcbiAgc2hhMTogc2hhLnNoYTEsXG4gIHNoYTI1Njogc2hhLnNoYTI1NixcbiAgc2hhMjI0OiBzaGEuc2hhMjI0LFxuICBzaGEzODQ6IHNoYS5zaGEzODQsXG4gIHNoYTUxMjogc2hhLnNoYTUxMixcbiAgcmlwZW1kOiByZXF1aXJlKCcuL3JpcGUtbWQuanMnKSxcblxuICAvKipcbiAgICogQ3JlYXRlIGEgaGFzaCBvbiB0aGUgc3BlY2lmaWVkIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEhhc2ggYWxnb3JpdGhtIHR5cGUgKHNlZSBSRkM0ODgwIDkuNClcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBoYXNoZWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBoYXNoIHZhbHVlXG4gICAqL1xuICBkaWdlc3Q6IGZ1bmN0aW9uKGFsZ28sIGRhdGEpIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gLSBNRDUgW0hBQ11cbiAgICAgICAgcmV0dXJuIHRoaXMubWQ1KGRhdGEpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGExKGRhdGEpO1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyAtIFJJUEUtTUQvMTYwIFtIQUNdXG4gICAgICAgIHJldHVybiB0aGlzLnJpcGVtZChkYXRhKTtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgLy8gLSBTSEEyNTYgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTI1NihkYXRhKTtcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgLy8gLSBTSEEzODQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTM4NChkYXRhKTtcbiAgICAgIGNhc2UgMTA6XG4gICAgICAgIC8vIC0gU0hBNTEyIFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGE1MTIoZGF0YSk7XG4gICAgICBjYXNlIDExOlxuICAgICAgICAvLyAtIFNIQTIyNCBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMjI0KGRhdGEpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhhc2ggZnVuY3Rpb24uJyk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBoYXNoIHNpemUgaW4gYnl0ZXMgb2YgdGhlIHNwZWNpZmllZCBoYXNoIGFsZ29yaXRobSB0eXBlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChTZWUgUkZDNDg4MCA5LjQpXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IFNpemUgaW4gYnl0ZXMgb2YgdGhlIHJlc3VsdGluZyBoYXNoXG4gICAqL1xuICBnZXRIYXNoQnl0ZUxlbmd0aDogZnVuY3Rpb24oYWxnbykge1xuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAxOlxuICAgICAgICAvLyAtIE1ENSBbSEFDXVxuICAgICAgICByZXR1cm4gMTY7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIC0gU0hBLTEgW0ZJUFMxODBdXG4gICAgICBjYXNlIDM6XG4gICAgICAgIC8vIC0gUklQRS1NRC8xNjAgW0hBQ11cbiAgICAgICAgcmV0dXJuIDIwO1xuICAgICAgY2FzZSA4OlxuICAgICAgICAvLyAtIFNIQTI1NiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIDMyO1xuICAgICAgY2FzZSA5OlxuICAgICAgICAvLyAtIFNIQTM4NCBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIDQ4XG4gICAgICBjYXNlIDEwOlxuICAgICAgICAvLyAtIFNIQTUxMiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIDY0O1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gLSBTSEEyMjQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiAyODtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoYXNoIGFsZ29yaXRobS4nKTtcbiAgICB9XG4gIH1cblxufVxuIiwiLyoqXG4gKiBBIGZhc3QgTUQ1IEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb25cbiAqIENvcHlyaWdodCAoYykgMjAxMiBKb3NlcGggTXllcnNcbiAqIGh0dHA6Ly93d3cubXllcnNkYWlseS5vcmcvam9zZXBoL2phdmFzY3JpcHQvbWQ1LXRleHQuaHRtbFxuICpcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZCBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmVcbiAqIGFuZCBpdHMgZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2VzIGFuZCB3aXRob3V0XG4gKiBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQgcHJvdmlkZWQgdGhhdCB0aGlzIGNvcHlyaWdodCBub3RpY2VcbiAqIGFwcGVhcnMgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiBPZiBjb3Vyc2UsIHRoaXMgc29mdCBpcyBwcm92aWRlZCBcImFzIGlzXCIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWRcbiAqIHdhcnJhbnR5IG9mIGFueSBraW5kLlxuICovXG5cbi8qKiBAbW9kdWxlIGNyeXB0by9oYXNoL21kNSAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvdXRpbC5qcycpO1xuXG5mdW5jdGlvbiBNRDUoZW50cmVlKSB7XG4gIHZhciBoZXggPSBtZDUoZW50cmVlKTtcbiAgdmFyIGJpbiA9IHV0aWwuaGV4MmJpbihoZXgpO1xuICByZXR1cm4gYmluO1xufVxuXG5mdW5jdGlvbiBtZDVjeWNsZSh4LCBrKSB7XG4gIHZhciBhID0geFswXSxcbiAgICBiID0geFsxXSxcbiAgICBjID0geFsyXSxcbiAgICBkID0geFszXTtcblxuICBhID0gZmYoYSwgYiwgYywgZCwga1swXSwgNywgLTY4MDg3NjkzNik7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzJdLCAxNywgNjA2MTA1ODE5KTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbOF0sIDcsIDE3NzAwMzU0MTYpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1s5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbMTBdLCAxNywgLTQyMDYzKTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICBhID0gZmYoYSwgYiwgYywgZCwga1sxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1sxM10sIDEyLCAtNDAzNDExMDEpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1sxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuXG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbMF0sIDIwLCAtMzczODk3MzAyKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbNV0sIDUsIC03MDE1NTg2OTEpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxMF0sIDksIDM4MDE2MDgzKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzRdLCAyMCwgLTQwNTUzNzg0OCk7XG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzldLCA1LCA1Njg0NDY0MzgpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxNF0sIDksIC0xMDE5ODAzNjkwKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbM10sIDE0LCAtMTg3MzYzOTYxKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbOF0sIDIwLCAxMTYzNTMxNTAxKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbMTNdLCA1LCAtMTQ0NDY4MTQ2Nyk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzJdLCA5LCAtNTE0MDM3ODQpO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1s3XSwgMTQsIDE3MzUzMjg0NzMpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1sxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG5cbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbNV0sIDQsIC0zNzg1NTgpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1s4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTFdLCAxNiwgMTgzOTAzMDU2Mik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzFdLCA0LCAtMTUzMDk5MjA2MCk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzRdLCAxMSwgMTI3Mjg5MzM1Myk7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzddLCAxNiwgLTE1NTQ5NzYzMik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzEwXSwgMjMsIC0xMDk0NzMwNjQwKTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbMTNdLCA0LCA2ODEyNzkxNzQpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1swXSwgMTEsIC0zNTg1MzcyMjIpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1szXSwgMTYsIC03MjI1MjE5NzkpO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1s2XSwgMjMsIDc2MDI5MTg5KTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbOV0sIDQsIC02NDAzNjQ0ODcpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1sxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTVdLCAxNiwgNTMwNzQyNTIwKTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICBhID0gaWkoYSwgYiwgYywgZCwga1swXSwgNiwgLTE5ODYzMDg0NCk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzddLCAxMCwgMTEyNjg5MTQxNSk7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbNV0sIDIxLCAtNTc0MzQwNTUpO1xuICBhID0gaWkoYSwgYiwgYywgZCwga1sxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1szXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbMTBdLCAxNSwgLTEwNTE1MjMpO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1sxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbOF0sIDYsIDE4NzMzMTMzNTkpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1sxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1s2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1syXSwgMTUsIDcxODc4NzI1OSk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgeFswXSA9IGFkZDMyKGEsIHhbMF0pO1xuICB4WzFdID0gYWRkMzIoYiwgeFsxXSk7XG4gIHhbMl0gPSBhZGQzMihjLCB4WzJdKTtcbiAgeFszXSA9IGFkZDMyKGQsIHhbM10pO1xuXG59XG5cbmZ1bmN0aW9uIGNtbihxLCBhLCBiLCB4LCBzLCB0KSB7XG4gIGEgPSBhZGQzMihhZGQzMihhLCBxKSwgYWRkMzIoeCwgdCkpO1xuICByZXR1cm4gYWRkMzIoKGEgPDwgcykgfCAoYSA+Pj4gKDMyIC0gcykpLCBiKTtcbn1cblxuZnVuY3Rpb24gZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gZ2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gaGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIGlpKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNTEocykge1xuICB0eHQgPSAnJztcbiAgdmFyIG4gPSBzLmxlbmd0aCxcbiAgICBzdGF0ZSA9IFsxNzMyNTg0MTkzLCAtMjcxNzMzODc5LCAtMTczMjU4NDE5NCwgMjcxNzMzODc4XSxcbiAgICBpO1xuICBmb3IgKGkgPSA2NDsgaSA8PSBzLmxlbmd0aDsgaSArPSA2NCkge1xuICAgIG1kNWN5Y2xlKHN0YXRlLCBtZDVibGsocy5zdWJzdHJpbmcoaSAtIDY0LCBpKSkpO1xuICB9XG4gIHMgPSBzLnN1YnN0cmluZyhpIC0gNjQpO1xuICB2YXIgdGFpbCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgZm9yIChpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspXG4gICAgdGFpbFtpID4+IDJdIHw9IHMuY2hhckNvZGVBdChpKSA8PCAoKGkgJSA0KSA8PCAzKTtcbiAgdGFpbFtpID4+IDJdIHw9IDB4ODAgPDwgKChpICUgNCkgPDwgMyk7XG4gIGlmIChpID4gNTUpIHtcbiAgICBtZDVjeWNsZShzdGF0ZSwgdGFpbCk7XG4gICAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHRhaWxbaV0gPSAwO1xuICB9XG4gIHRhaWxbMTRdID0gbiAqIDg7XG4gIG1kNWN5Y2xlKHN0YXRlLCB0YWlsKTtcbiAgcmV0dXJuIHN0YXRlO1xufVxuXG4vKiB0aGVyZSBuZWVkcyB0byBiZSBzdXBwb3J0IGZvciBVbmljb2RlIGhlcmUsXG4gKiB1bmxlc3Mgd2UgcHJldGVuZCB0aGF0IHdlIGNhbiByZWRlZmluZSB0aGUgTUQtNVxuICogYWxnb3JpdGhtIGZvciBtdWx0aS1ieXRlIGNoYXJhY3RlcnMgKHBlcmhhcHNcbiAqIGJ5IGFkZGluZyBldmVyeSBmb3VyIDE2LWJpdCBjaGFyYWN0ZXJzIGFuZFxuICogc2hvcnRlbmluZyB0aGUgc3VtIHRvIDMyIGJpdHMpLiBPdGhlcndpc2VcbiAqIEkgc3VnZ2VzdCBwZXJmb3JtaW5nIE1ELTUgYXMgaWYgZXZlcnkgY2hhcmFjdGVyXG4gKiB3YXMgdHdvIGJ5dGVzLS1lLmcuLCAwMDQwIDAwMjUgPSBAJS0tYnV0IHRoZW5cbiAqIGhvdyB3aWxsIGFuIG9yZGluYXJ5IE1ELTUgc3VtIGJlIG1hdGNoZWQ/XG4gKiBUaGVyZSBpcyBubyB3YXkgdG8gc3RhbmRhcmRpemUgdGV4dCB0byBzb21ldGhpbmdcbiAqIGxpa2UgVVRGLTggYmVmb3JlIHRyYW5zZm9ybWF0aW9uOyBzcGVlZCBjb3N0IGlzXG4gKiB1dHRlcmx5IHByb2hpYml0aXZlLiBUaGUgSmF2YVNjcmlwdCBzdGFuZGFyZFxuICogaXRzZWxmIG5lZWRzIHRvIGxvb2sgYXQgdGhpczogaXQgc2hvdWxkIHN0YXJ0XG4gKiBwcm92aWRpbmcgYWNjZXNzIHRvIHN0cmluZ3MgYXMgcHJlZm9ybWVkIFVURi04XG4gKiA4LWJpdCB1bnNpZ25lZCB2YWx1ZSBhcnJheXMuXG4gKi9cbmZ1bmN0aW9uIG1kNWJsayhzKSB7IC8qIEkgZmlndXJlZCBnbG9iYWwgd2FzIGZhc3Rlci4gICAqL1xuICB2YXIgbWQ1YmxrcyA9IFtdLFxuICAgIGk7IC8qIEFuZHkgS2luZyBzYWlkIGRvIGl0IHRoaXMgd2F5LiAqL1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkgKz0gNCkge1xuICAgIG1kNWJsa3NbaSA+PiAyXSA9IHMuY2hhckNvZGVBdChpKSArIChzLmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpICsgKHMuY2hhckNvZGVBdChpICsgMikgPDwgMTYpICsgKHMuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcbiAgfVxuICByZXR1cm4gbWQ1Ymxrcztcbn1cblxudmFyIGhleF9jaHIgPSAnMDEyMzQ1Njc4OWFiY2RlZicuc3BsaXQoJycpO1xuXG5mdW5jdGlvbiByaGV4KG4pIHtcbiAgdmFyIHMgPSAnJyxcbiAgICBqID0gMDtcbiAgZm9yICg7IGogPCA0OyBqKyspXG4gICAgcyArPSBoZXhfY2hyWyhuID4+IChqICogOCArIDQpKSAmIDB4MEZdICsgaGV4X2NoclsobiA+PiAoaiAqIDgpKSAmIDB4MEZdO1xuICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gaGV4KHgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKVxuICAgIHhbaV0gPSByaGV4KHhbaV0pO1xuICByZXR1cm4geC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gbWQ1KHMpIHtcbiAgcmV0dXJuIGhleChtZDUxKHMpKTtcbn1cblxuLyogdGhpcyBmdW5jdGlvbiBpcyBtdWNoIGZhc3RlcixcbnNvIGlmIHBvc3NpYmxlIHdlIHVzZSBpdC4gU29tZSBJRXNcbmFyZSB0aGUgb25seSBvbmVzIEkga25vdyBvZiB0aGF0XG5uZWVkIHRoZSBpZGlvdGljIHNlY29uZCBmdW5jdGlvbixcbmdlbmVyYXRlZCBieSBhbiBpZiBjbGF1c2UuICAqL1xuXG5mdW5jdGlvbiBhZGQzMihhLCBiKSB7XG4gIHJldHVybiAoYSArIGIpICYgMHhGRkZGRkZGRjtcbn1cblxuaWYgKG1kNSgnaGVsbG8nKSAhPSAnNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTInKSB7XG4gIGZ1bmN0aW9uIGFkZDMyKHgsIHkpIHtcbiAgICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLFxuICAgICAgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gICAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNRDVcbiIsIi8qXG4gKiBDcnlwdG9NWCBUb29sc1xuICogQ29weXJpZ2h0IChDKSAyMDA0IC0gMjAwNiBEZXJlayBCdWl0ZW5odWlzXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyXG4gKiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3LCBVU0EuXG4gKi9cblxuLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG4gKi9cblxuLyoqIEBtb2R1bGUgY3J5cHRvL2hhc2gvcmlwZS1tZCAqL1xuXG52YXIgUk1Ec2l6ZSA9IDE2MDtcbnZhciBYID0gbmV3IEFycmF5KCk7XG5cbmZ1bmN0aW9uIFJPTCh4LCBuKSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKSk7XG59XG5cbmZ1bmN0aW9uIEYoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcih4IF4geSBeIHopO1xufVxuXG5mdW5jdGlvbiBHKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggJiB5KSB8ICh+eCAmIHopKTtcbn1cblxuZnVuY3Rpb24gSCh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4IHwgfnkpIF4geik7XG59XG5cbmZ1bmN0aW9uIEkoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCAmIHopIHwgKHkgJiB+eikpO1xufVxuXG5mdW5jdGlvbiBKKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoeCBeICh5IHwgfnopKTtcbn1cblxuZnVuY3Rpb24gbWl4T25lUm91bmQoYSwgYiwgYywgZCwgZSwgeCwgcywgcm91bmROdW1iZXIpIHtcbiAgc3dpdGNoIChyb3VuZE51bWJlcikge1xuICAgIGNhc2UgMDpcbiAgICAgIGEgKz0gRihiLCBjLCBkKSArIHggKyAweDAwMDAwMDAwO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgYSArPSBHKGIsIGMsIGQpICsgeCArIDB4NWE4Mjc5OTk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBhICs9IEgoYiwgYywgZCkgKyB4ICsgMHg2ZWQ5ZWJhMTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGEgKz0gSShiLCBjLCBkKSArIHggKyAweDhmMWJiY2RjO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgYSArPSBKKGIsIGMsIGQpICsgeCArIDB4YTk1M2ZkNGU7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDU6XG4gICAgICBhICs9IEooYiwgYywgZCkgKyB4ICsgMHg1MGEyOGJlNjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNjpcbiAgICAgIGEgKz0gSShiLCBjLCBkKSArIHggKyAweDVjNGRkMTI0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA3OlxuICAgICAgYSArPSBIKGIsIGMsIGQpICsgeCArIDB4NmQ3MDNlZjM7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDg6XG4gICAgICBhICs9IEcoYiwgYywgZCkgKyB4ICsgMHg3YTZkNzZlOTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgOTpcbiAgICAgIGEgKz0gRihiLCBjLCBkKSArIHggKyAweDAwMDAwMDAwO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgZG9jdW1lbnQud3JpdGUoXCJCb2d1cyByb3VuZCBudW1iZXJcIik7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIGEgPSBST0woYSwgcykgKyBlO1xuICBjID0gUk9MKGMsIDEwKTtcblxuICBhICY9IDB4ZmZmZmZmZmY7XG4gIGIgJj0gMHhmZmZmZmZmZjtcbiAgYyAmPSAweGZmZmZmZmZmO1xuICBkICY9IDB4ZmZmZmZmZmY7XG4gIGUgJj0gMHhmZmZmZmZmZjtcblxuICB2YXIgcmV0QmxvY2sgPSBuZXcgQXJyYXkoKTtcbiAgcmV0QmxvY2tbMF0gPSBhO1xuICByZXRCbG9ja1sxXSA9IGI7XG4gIHJldEJsb2NrWzJdID0gYztcbiAgcmV0QmxvY2tbM10gPSBkO1xuICByZXRCbG9ja1s0XSA9IGU7XG4gIHJldEJsb2NrWzVdID0geDtcbiAgcmV0QmxvY2tbNl0gPSBzO1xuXG4gIHJldHVybiByZXRCbG9jaztcbn1cblxuZnVuY3Rpb24gTURpbml0KE1EYnVmKSB7XG4gIE1EYnVmWzBdID0gMHg2NzQ1MjMwMTtcbiAgTURidWZbMV0gPSAweGVmY2RhYjg5O1xuICBNRGJ1ZlsyXSA9IDB4OThiYWRjZmU7XG4gIE1EYnVmWzNdID0gMHgxMDMyNTQ3NjtcbiAgTURidWZbNF0gPSAweGMzZDJlMWYwO1xufVxuXG52YXIgUk9McyA9IFtcbiAgWzExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOF0sXG4gIFs3LCA2LCA4LCAxMywgMTEsIDksIDcsIDE1LCA3LCAxMiwgMTUsIDksIDExLCA3LCAxMywgMTJdLFxuICBbMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1XSxcbiAgWzExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMl0sXG4gIFs5LCAxNSwgNSwgMTEsIDYsIDgsIDEzLCAxMiwgNSwgMTIsIDEzLCAxNCwgMTEsIDgsIDUsIDZdLFxuICBbOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2XSxcbiAgWzksIDEzLCAxNSwgNywgMTIsIDgsIDksIDExLCA3LCA3LCAxMiwgNywgNiwgMTUsIDEzLCAxMV0sXG4gIFs5LCA3LCAxNSwgMTEsIDgsIDYsIDYsIDE0LCAxMiwgMTMsIDUsIDE0LCAxMywgMTMsIDcsIDVdLFxuICBbMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4XSxcbiAgWzgsIDUsIDEyLCA5LCAxMiwgNSwgMTQsIDYsIDgsIDEzLCA2LCA1LCAxNSwgMTMsIDExLCAxMV1cbl07XG5cbnZhciBpbmRleGVzID0gW1xuICBbMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNV0sXG4gIFs3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4XSxcbiAgWzMsIDEwLCAxNCwgNCwgOSwgMTUsIDgsIDEsIDIsIDcsIDAsIDYsIDEzLCAxMSwgNSwgMTJdLFxuICBbMSwgOSwgMTEsIDEwLCAwLCA4LCAxMiwgNCwgMTMsIDMsIDcsIDE1LCAxNCwgNSwgNiwgMl0sXG4gIFs0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXSxcbiAgWzUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTJdLFxuICBbNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMl0sXG4gIFsxNSwgNSwgMSwgMywgNywgMTQsIDYsIDksIDExLCA4LCAxMiwgMiwgMTAsIDAsIDQsIDEzXSxcbiAgWzgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTRdLFxuICBbMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMV1cbl07XG5cbmZ1bmN0aW9uIGNvbXByZXNzKE1EYnVmLCBYKSB7XG4gIGJsb2NrQSA9IG5ldyBBcnJheSgpO1xuICBibG9ja0IgPSBuZXcgQXJyYXkoKTtcblxuICB2YXIgcmV0QmxvY2s7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA1OyBpKyspIHtcbiAgICBibG9ja0FbaV0gPSBuZXcgTnVtYmVyKE1EYnVmW2ldKTtcbiAgICBibG9ja0JbaV0gPSBuZXcgTnVtYmVyKE1EYnVmW2ldKTtcbiAgfVxuXG4gIHZhciBzdGVwID0gMDtcbiAgZm9yICh2YXIgaiA9IDA7IGogPCA1OyBqKyspIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHJldEJsb2NrID0gbWl4T25lUm91bmQoXG4gICAgICAgIGJsb2NrQVsoc3RlcCArIDApICUgNV0sXG4gICAgICAgIGJsb2NrQVsoc3RlcCArIDEpICUgNV0sXG4gICAgICAgIGJsb2NrQVsoc3RlcCArIDIpICUgNV0sXG4gICAgICAgIGJsb2NrQVsoc3RlcCArIDMpICUgNV0sXG4gICAgICAgIGJsb2NrQVsoc3RlcCArIDQpICUgNV0sXG4gICAgICAgIFhbaW5kZXhlc1tqXVtpXV0sXG4gICAgICAgIFJPTHNbal1baV0sXG4gICAgICAgIGopO1xuXG4gICAgICBibG9ja0FbKHN0ZXAgKyAwKSAlIDVdID0gcmV0QmxvY2tbMF07XG4gICAgICBibG9ja0FbKHN0ZXAgKyAxKSAlIDVdID0gcmV0QmxvY2tbMV07XG4gICAgICBibG9ja0FbKHN0ZXAgKyAyKSAlIDVdID0gcmV0QmxvY2tbMl07XG4gICAgICBibG9ja0FbKHN0ZXAgKyAzKSAlIDVdID0gcmV0QmxvY2tbM107XG4gICAgICBibG9ja0FbKHN0ZXAgKyA0KSAlIDVdID0gcmV0QmxvY2tbNF07XG5cbiAgICAgIHN0ZXAgKz0gNDtcbiAgICB9XG4gIH1cblxuICBzdGVwID0gMDtcbiAgZm9yICh2YXIgaiA9IDU7IGogPCAxMDsgaisrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICByZXRCbG9jayA9IG1peE9uZVJvdW5kKFxuICAgICAgICBibG9ja0JbKHN0ZXAgKyAwKSAlIDVdLFxuICAgICAgICBibG9ja0JbKHN0ZXAgKyAxKSAlIDVdLFxuICAgICAgICBibG9ja0JbKHN0ZXAgKyAyKSAlIDVdLFxuICAgICAgICBibG9ja0JbKHN0ZXAgKyAzKSAlIDVdLFxuICAgICAgICBibG9ja0JbKHN0ZXAgKyA0KSAlIDVdLFxuICAgICAgICBYW2luZGV4ZXNbal1baV1dLFxuICAgICAgICBST0xzW2pdW2ldLFxuICAgICAgICBqKTtcblxuICAgICAgYmxvY2tCWyhzdGVwICsgMCkgJSA1XSA9IHJldEJsb2NrWzBdO1xuICAgICAgYmxvY2tCWyhzdGVwICsgMSkgJSA1XSA9IHJldEJsb2NrWzFdO1xuICAgICAgYmxvY2tCWyhzdGVwICsgMikgJSA1XSA9IHJldEJsb2NrWzJdO1xuICAgICAgYmxvY2tCWyhzdGVwICsgMykgJSA1XSA9IHJldEJsb2NrWzNdO1xuICAgICAgYmxvY2tCWyhzdGVwICsgNCkgJSA1XSA9IHJldEJsb2NrWzRdO1xuXG4gICAgICBzdGVwICs9IDQ7XG4gICAgfVxuICB9XG5cbiAgYmxvY2tCWzNdICs9IGJsb2NrQVsyXSArIE1EYnVmWzFdO1xuICBNRGJ1ZlsxXSA9IE1EYnVmWzJdICsgYmxvY2tBWzNdICsgYmxvY2tCWzRdO1xuICBNRGJ1ZlsyXSA9IE1EYnVmWzNdICsgYmxvY2tBWzRdICsgYmxvY2tCWzBdO1xuICBNRGJ1ZlszXSA9IE1EYnVmWzRdICsgYmxvY2tBWzBdICsgYmxvY2tCWzFdO1xuICBNRGJ1Zls0XSA9IE1EYnVmWzBdICsgYmxvY2tBWzFdICsgYmxvY2tCWzJdO1xuICBNRGJ1ZlswXSA9IGJsb2NrQlszXTtcbn1cblxuZnVuY3Rpb24gemVyb1goWCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICBYW2ldID0gMDtcbiAgfVxufVxuXG5mdW5jdGlvbiBNRGZpbmlzaChNRGJ1Ziwgc3RycHRyLCBsc3dsZW4sIG1zd2xlbikge1xuICB2YXIgWCA9IG5ldyBBcnJheSgxNik7XG4gIHplcm9YKFgpO1xuXG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAobHN3bGVuICYgNjMpOyBpKyspIHtcbiAgICBYW2kgPj4+IDJdIF49IChzdHJwdHIuY2hhckNvZGVBdChqKyspICYgMjU1KSA8PCAoOCAqIChpICYgMykpO1xuICB9XG5cbiAgWFsobHN3bGVuID4+PiAyKSAmIDE1XSBePSAxIDw8ICg4ICogKGxzd2xlbiAmIDMpICsgNyk7XG5cbiAgaWYgKChsc3dsZW4gJiA2MykgPiA1NSkge1xuICAgIGNvbXByZXNzKE1EYnVmLCBYKTtcbiAgICB2YXIgWCA9IG5ldyBBcnJheSgxNik7XG4gICAgemVyb1goWCk7XG4gIH1cblxuICBYWzE0XSA9IGxzd2xlbiA8PCAzO1xuICBYWzE1XSA9IChsc3dsZW4gPj4+IDI5KSB8IChtc3dsZW4gPDwgMyk7XG5cbiAgY29tcHJlc3MoTURidWYsIFgpO1xufVxuXG5mdW5jdGlvbiBCWVRFU19UT19EV09SRChmb3VyQ2hhcnMpIHtcbiAgdmFyIHRtcCA9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgzKSAmIDI1NSkgPDwgMjQ7XG4gIHRtcCB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMikgJiAyNTUpIDw8IDE2O1xuICB0bXAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDEpICYgMjU1KSA8PCA4O1xuICB0bXAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDApICYgMjU1KTtcblxuICByZXR1cm4gdG1wO1xufVxuXG5mdW5jdGlvbiBSTUQobWVzc2FnZSkge1xuICB2YXIgTURidWYgPSBuZXcgQXJyYXkoUk1Ec2l6ZSAvIDMyKTtcbiAgdmFyIGhhc2hjb2RlID0gbmV3IEFycmF5KFJNRHNpemUgLyA4KTtcbiAgdmFyIGxlbmd0aDtcbiAgdmFyIG5ieXRlcztcblxuICBNRGluaXQoTURidWYpO1xuICBsZW5ndGggPSBtZXNzYWdlLmxlbmd0aDtcblxuICB2YXIgWCA9IG5ldyBBcnJheSgxNik7XG4gIHplcm9YKFgpO1xuXG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgbmJ5dGVzID0gbGVuZ3RoOyBuYnl0ZXMgPiA2MzsgbmJ5dGVzIC09IDY0KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBYW2ldID0gQllURVNfVE9fRFdPUkQobWVzc2FnZS5zdWJzdHIoaiwgNCkpO1xuICAgICAgaiArPSA0O1xuICAgIH1cbiAgICBjb21wcmVzcyhNRGJ1ZiwgWCk7XG4gIH1cblxuICBNRGZpbmlzaChNRGJ1ZiwgbWVzc2FnZS5zdWJzdHIoaiksIGxlbmd0aCwgMCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBSTURzaXplIC8gODsgaSArPSA0KSB7XG4gICAgaGFzaGNvZGVbaV0gPSBNRGJ1ZltpID4+PiAyXSAmIDI1NTtcbiAgICBoYXNoY29kZVtpICsgMV0gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDgpICYgMjU1O1xuICAgIGhhc2hjb2RlW2kgKyAyXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gMTYpICYgMjU1O1xuICAgIGhhc2hjb2RlW2kgKyAzXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gMjQpICYgMjU1O1xuICB9XG5cbiAgcmV0dXJuIGhhc2hjb2RlO1xufVxuXG5cbmZ1bmN0aW9uIFJNRHN0cmluZyhtZXNzYWdlKSB7XG4gIHZhciBoYXNoY29kZSA9IFJNRChtZXNzYWdlKTtcbiAgdmFyIHJldFN0cmluZyA9IFwiXCI7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBSTURzaXplIC8gODsgaSsrKSB7XG4gICAgcmV0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaGNvZGVbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHJldFN0cmluZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSTURzdHJpbmc7XG4iLCIvKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNIQSBmYW1pbHkgb2YgaGFzaGVzLCBhcyBkZWZpbmVkIGluIEZJUFMgXG4gKiBQVUIgMTgwLTIgYXMgd2VsbCBhcyB0aGUgY29ycmVzcG9uZGluZyBITUFDIGltcGxlbWVudGF0aW9uIGFzIGRlZmluZWQgaW5cbiAqIEZJUFMgUFVCIDE5OGFcbiAqXG4gKiBWZXJzaW9uIDEuMyBDb3B5cmlnaHQgQnJpYW4gVHVyZWsgMjAwOC0yMDEwXG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vanNzaGEuc291cmNlZm9yZ2UubmV0LyBmb3IgbW9yZSBpbmZvcm1hdGlvblxuICpcbiAqIFNldmVyYWwgZnVuY3Rpb25zIHRha2VuIGZyb20gUGF1bCBKb2huc29uXG4gKi9cblxuLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG4gKiBcbiAqIFRoaXMgY29kZSBoYXMgYmVlbiBzbGlnaHRseSBtb2RpZmllZCBkaXJlY3Qgc3RyaW5nIG91dHB1dDpcbiAqIC0gYmluMmJzdHIgaGFzIGJlZW4gYWRkZWRcbiAqIC0gZm9sbG93aW5nIHdyYXBwZXJzIG9mIHRoaXMgbGlicmFyeSBoYXZlIGJlZW4gYWRkZWQ6XG4gKiAgIC0gc3RyX3NoYTFcbiAqICAgLSBzdHJfc2hhMjU2XG4gKiAgIC0gc3RyX3NoYTIyNFxuICogICAtIHN0cl9zaGEzODRcbiAqICAgLSBzdHJfc2hhNTEyXG4gKi9cblxuLyoqIEBtb2R1bGUgY3J5cHRvL2hhc2gvc2hhICovXG5cbnZhciBqc1NIQSA9IChmdW5jdGlvbigpIHtcblxuICAvKlxuICAgKiBDb25maWd1cmFibGUgdmFyaWFibGVzLiBEZWZhdWx0cyB0eXBpY2FsbHkgd29ya1xuICAgKi9cbiAgLyogTnVtYmVyIG9mIEJpdHMgUGVyIGNoYXJhY3RlciAoOCBmb3IgQVNDSUksIDE2IGZvciBVbmljb2RlKSAqL1xuICB2YXIgY2hhclNpemUgPSA4LFxuICAgIC8qIGJhc2UtNjQgcGFkIGNoYXJhY3Rlci4gXCI9XCIgZm9yIHN0cmljdCBSRkMgY29tcGxpYW5jZSAqL1xuICAgIGI2NHBhZCA9IFwiXCIsXG4gICAgLyogaGV4IG91dHB1dCBmb3JtYXQuIDAgLSBsb3dlcmNhc2U7IDEgLSB1cHBlcmNhc2UgKi9cbiAgICBoZXhDYXNlID0gMCxcblxuICAgIC8qXG4gICAgICogSW50XzY0IGlzIGEgb2JqZWN0IGZvciAyIDMyLWJpdCBudW1iZXJzIGVtdWxhdGluZyBhIDY0LWJpdCBudW1iZXJcbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtc2ludF8zMiBUaGUgbW9zdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsc2ludF8zMiBUaGUgbGVhc3Qgc2lnbmlmaWNhbnQgMzItYml0cyBvZiBhIDY0LWJpdCBudW1iZXJcbiAgICAgKi9cbiAgICBJbnRfNjQgPSBmdW5jdGlvbihtc2ludF8zMiwgbHNpbnRfMzIpIHtcbiAgICAgIHRoaXMuaGlnaE9yZGVyID0gbXNpbnRfMzI7XG4gICAgICB0aGlzLmxvd09yZGVyID0gbHNpbnRfMzI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG4gICAgICogSWYgY2hhclNpemUgaXMgQVNDSUksIGNoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpLWJ5dGUgc2lsZW50bHlcbiAgICAgKiBpZ25vcmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgc3RyMmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbWFzayA9ICgxIDw8IGNoYXJTaXplKSAtIDEsXG4gICAgICAgIGxlbmd0aCA9IHN0ci5sZW5ndGggKiBjaGFyU2l6ZSxcbiAgICAgICAgaTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBjaGFyU2l6ZSkge1xuICAgICAgICBiaW5baSA+PiA1XSB8PSAoc3RyLmNoYXJDb2RlQXQoaSAvIGNoYXJTaXplKSAmIG1hc2spIDw8XG4gICAgICAgICAgKDMyIC0gY2hhclNpemUgLSAoaSAlIDMyKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiaW47XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIGhleCBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3Jkc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgaGV4MmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbGVuZ3RoID0gc3RyLmxlbmd0aCxcbiAgICAgICAgaSwgbnVtO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgbnVtID0gcGFyc2VJbnQoc3RyLnN1YnN0cihpLCAyKSwgMTYpO1xuICAgICAgICBpZiAoIWlzTmFOKG51bSkpIHtcbiAgICAgICAgICBiaW5baSA+PiAzXSB8PSBudW0gPDwgKDI0IC0gKDQgKiAoaSAlIDgpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFwiSU5WQUxJRCBIRVggU1RSSU5HXCI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJpbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBoZXggc3RyaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBiaW5hcnJheSBBcnJheSBvZiBpbnRlZ2VycyB0byBiZSBjb252ZXJ0ZWQgdG8gaGV4aWRlY2ltYWxcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBIZXhpZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyIGluIFN0cmluZyBmb3JtXG4gICAgICovXG4gICAgYmluYjJoZXggPSBmdW5jdGlvbihiaW5hcnJheSkge1xuICAgICAgdmFyIGhleF90YWIgPSAoaGV4Q2FzZSkgPyBcIjAxMjM0NTY3ODlBQkNERUZcIiA6IFwiMDEyMzQ1Njc4OWFiY2RlZlwiLFxuICAgICAgICBzdHIgPSBcIlwiLFxuICAgICAgICBsZW5ndGggPSBiaW5hcnJheS5sZW5ndGggKiA0LFxuICAgICAgICBpLCBzcmNCeXRlO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgc3JjQnl0ZSA9IGJpbmFycmF5W2kgPj4gMl0gPj4gKCgzIC0gKGkgJSA0KSkgKiA4KTtcbiAgICAgICAgc3RyICs9IGhleF90YWIuY2hhckF0KChzcmNCeXRlID4+IDQpICYgMHhGKSArXG4gICAgICAgICAgaGV4X3RhYi5jaGFyQXQoc3JjQnl0ZSAmIDB4Rik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgYmFzZS02NCBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYmluYXJyYXkgQXJyYXkgb2YgaW50ZWdlcnMgdG8gYmUgY29udmVydGVkIHRvIGJhc2UtNjRcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBCYXNlLTY0IGVuY29kZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybVxuICAgICAqL1xuICAgIGJpbmIyYjY0ID0gZnVuY3Rpb24oYmluYXJyYXkpIHtcbiAgICAgIHZhciB0YWIgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIiArXG4gICAgICAgIFwiMDEyMzQ1Njc4OSsvXCIsXG4gICAgICAgIHN0ciA9IFwiXCIsXG4gICAgICAgIGxlbmd0aCA9IGJpbmFycmF5Lmxlbmd0aCAqIDQsXG4gICAgICAgIGksIGosXG4gICAgICAgIHRyaXBsZXQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB0cmlwbGV0ID0gKCgoYmluYXJyYXlbaSA+PiAyXSA+PiA4ICogKDMgLSBpICUgNCkpICYgMHhGRikgPDwgMTYpIHxcbiAgICAgICAgICAoKChiaW5hcnJheVtpICsgMSA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDEpICUgNCkpICYgMHhGRikgPDwgOCkgfFxuICAgICAgICAgICgoYmluYXJyYXlbaSArIDIgPj4gMl0gPj4gOCAqICgzIC0gKGkgKyAyKSAlIDQpKSAmIDB4RkYpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgNDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKGkgKiA4ICsgaiAqIDYgPD0gYmluYXJyYXkubGVuZ3RoICogMzIpIHtcbiAgICAgICAgICAgIHN0ciArPSB0YWIuY2hhckF0KCh0cmlwbGV0ID4+IDYgKiAoMyAtIGopKSAmIDB4M0YpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHIgKz0gYjY0cGFkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBzdHJpbmdcbiAgICAgKi9cbiAgICBiaW5iMnN0ciA9IGZ1bmN0aW9uKGJpbikge1xuICAgICAgdmFyIHN0ciA9IFwiXCI7XG4gICAgICB2YXIgbWFzayA9ICgxIDw8IDgpIC0gMTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aCAqIDMyOyBpICs9IDgpXG4gICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChiaW5baSA+PiA1XSA+Pj4gKDI0IC0gaSAlIDMyKSkgJiBtYXNrKTtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgY2lyY3VsYXIgcm90YXRlIGxlZnRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90bF8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA+Pj4gbikgfCAoeCA8PCAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl82NCA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIGlmIChuIDw9IDMyKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpLCAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpLCAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfMzIgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICByZXR1cm4geCA+Pj4gbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfNjQgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICBpZiAobiA8PSAzMikge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICB4LmhpZ2hPcmRlciA+Pj4gbixcbiAgICAgICAgICB4Lmxvd09yZGVyID4+PiBuIHwgKHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICAwLFxuICAgICAgICAgIHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBQYXJpdHkgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwYXJpdHlfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gKHggJiB5KSBeICh+eCAmIHopO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geiBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeICh+eC5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlciksICh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXiAofngubG93T3JkZXIgJiB6Lmxvd09yZGVyKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgTWFqIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgbWFqXzMyID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHkgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB6IFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBtYWpfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeXG4gICAgICAgICh4LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSBeXG4gICAgICAgICh5LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSwgKHgubG93T3JkZXIgJiB5Lmxvd09yZGVyKSBeXG4gICAgICAgICh4Lmxvd09yZGVyICYgei5sb3dPcmRlcikgXlxuICAgICAgICAoeS5sb3dPcmRlciAmIHoubG93T3JkZXIpKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDIpIF4gcm90cl8zMih4LCAxMykgXiByb3RyXzMyKHgsIDIyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMjggPSByb3RyXzY0KHgsIDI4KSxcbiAgICAgICAgcm90cjM0ID0gcm90cl82NCh4LCAzNCksXG4gICAgICAgIHJvdHIzOSA9IHJvdHJfNjQoeCwgMzkpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjI4LmhpZ2hPcmRlciBeIHJvdHIzNC5oaWdoT3JkZXIgXiByb3RyMzkuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMjgubG93T3JkZXIgXiByb3RyMzQubG93T3JkZXIgXiByb3RyMzkubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgNikgXiByb3RyXzMyKHgsIDExKSBeIHJvdHJfMzIoeCwgMjUpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxNCA9IHJvdHJfNjQoeCwgMTQpLFxuICAgICAgICByb3RyMTggPSByb3RyXzY0KHgsIDE4KSxcbiAgICAgICAgcm90cjQxID0gcm90cl82NCh4LCA0MSk7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTQuaGlnaE9yZGVyIF4gcm90cjE4LmhpZ2hPcmRlciBeIHJvdHI0MS5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxNC5sb3dPcmRlciBeIHJvdHIxOC5sb3dPcmRlciBeIHJvdHI0MS5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTBfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCA3KSBeIHJvdHJfMzIoeCwgMTgpIF4gc2hyXzMyKHgsIDMpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWEwXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxID0gcm90cl82NCh4LCAxKSxcbiAgICAgICAgcm90cjggPSByb3RyXzY0KHgsIDgpLFxuICAgICAgICBzaHI3ID0gc2hyXzY0KHgsIDcpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjEuaGlnaE9yZGVyIF4gcm90cjguaGlnaE9yZGVyIF4gc2hyNy5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxLmxvd09yZGVyIF4gcm90cjgubG93T3JkZXIgXiBzaHI3Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDE3KSBeIHJvdHJfMzIoeCwgMTkpIF4gc2hyXzMyKHgsIDEwKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMTkgPSByb3RyXzY0KHgsIDE5KSxcbiAgICAgICAgcm90cjYxID0gcm90cl82NCh4LCA2MSksXG4gICAgICAgIHNocjYgPSBzaHJfNjQoeCwgNik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTkuaGlnaE9yZGVyIF4gcm90cjYxLmhpZ2hPcmRlciBeIHNocjYuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMTkubG93T3JkZXIgXiByb3RyNjEubG93T3JkZXIgXiBzaHI2Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF8zMl8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKHggPj4+IDE2KSArICh5ID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZvdXIgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzMyXzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3ID0gKGEgJiAweEZGRkYpICsgKGIgJiAweEZGRkYpICsgKGMgJiAweEZGRkYpICsgKGQgJiAweEZGRkYpLFxuICAgICAgICBtc3cgPSAoYSA+Pj4gMTYpICsgKGIgPj4+IDE2KSArIChjID4+PiAxNikgKyAoZCA+Pj4gMTYpICtcbiAgICAgICAgICAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZpdmUgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGUgVGhlIGZpZnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQgKyBlXG4gICAgICovXG4gICAgc2FmZUFkZF8zMl81ID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSkge1xuICAgICAgdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSArXG4gICAgICAgIChlICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKGEgPj4+IDE2KSArIChiID4+PiAxNikgKyAoYyA+Pj4gMTYpICsgKGQgPj4+IDE2KSArXG4gICAgICAgICAgKGUgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcblxuICAgICAgcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF82NF8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG4gICAgICBsc3cgPSAoeC5sb3dPcmRlciAmIDB4RkZGRikgKyAoeS5sb3dPcmRlciAmIDB4RkZGRik7XG4gICAgICBtc3cgPSAoeC5sb3dPcmRlciA+Pj4gMTYpICsgKHkubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICBsc3cgPSAoeC5oaWdoT3JkZXIgJiAweEZGRkYpICsgKHkuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9ICh4LmhpZ2hPcmRlciA+Pj4gMTYpICsgKHkuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBoaWdoT3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmb3VyIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzY0XzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7XG5cbiAgICAgIGxzdyA9IChhLmxvd09yZGVyICYgMHhGRkZGKSArIChiLmxvd09yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKTtcbiAgICAgIG1zdyA9IChhLmxvd09yZGVyID4+PiAxNikgKyAoYi5sb3dPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgPj4+IDE2KSArIChkLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZml2ZSA2NC1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeNjQuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGEgVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBjIFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBkIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBlIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkICsgZVxuICAgICAqL1xuICAgIHNhZmVBZGRfNjRfNSA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQsIGUpIHtcbiAgICAgIHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuICAgICAgbHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMubG93T3JkZXIgJiAweEZGRkYpICsgKGQubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGUubG93T3JkZXIgJiAweEZGRkYpO1xuICAgICAgbXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5sb3dPcmRlciA+Pj4gMTYpICsgKGQubG93T3JkZXIgPj4+IDE2KSArIChlLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChlLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG4gICAgICBtc3cgPSAoYS5oaWdoT3JkZXIgPj4+IDE2KSArIChiLmhpZ2hPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChlLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBTSEEtMSBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gbWVzc2FnZSBUaGUgYmluYXJ5IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcgdG9cbiAgICAgKlx0IGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUxlbiBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIFRoZSBhcnJheSBvZiBpbnRlZ2VycyByZXByZXNlbnRpbmcgdGhlIFNIQS0xIGhhc2ggb2YgbWVzc2FnZVxuICAgICAqL1xuICAgIGNvcmVTSEExID0gZnVuY3Rpb24obWVzc2FnZSwgbWVzc2FnZUxlbikge1xuICAgICAgdmFyIFcgPSBbXSxcbiAgICAgICAgYSwgYiwgYywgZCwgZSwgVCwgY2ggPSBjaF8zMixcbiAgICAgICAgcGFyaXR5ID0gcGFyaXR5XzMyLFxuICAgICAgICBtYWogPSBtYWpfMzIsXG4gICAgICAgIHJvdGwgPSByb3RsXzMyLFxuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzIsXG4gICAgICAgIGksIHQsXG4gICAgICAgIHNhZmVBZGRfNSA9IHNhZmVBZGRfMzJfNSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoLFxuICAgICAgICBIID0gW1xuICAgICAgICAgICAgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMFxuICAgICAgICBdLFxuICAgICAgICBLID0gW1xuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDZcbiAgICAgICAgXTtcblxuICAgICAgLyogQXBwZW5kICcxJyBhdCB0aGUgZW5kIG9mIHRoZSBiaW5hcnkgc3RyaW5nICovXG4gICAgICBtZXNzYWdlW21lc3NhZ2VMZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSAobWVzc2FnZUxlbiAlIDMyKSk7XG4gICAgICAvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3XG5cdFx0bGVuZ3RoIGlzIGEgbXVsdGlwbGUgb2YgNTEyLiAgTG9naWMgZG9lcyBub3Qgd29yayBmb3IgZXZlbiBtdWx0aXBsZXNcblx0XHRvZiA1MTIgYnV0IHRoZXJlIGNhbiBuZXZlciBiZSBldmVuIG11bHRpcGxlcyBvZiA1MTIgKi9cbiAgICAgIG1lc3NhZ2VbKCgobWVzc2FnZUxlbiArIDY1KSA+PiA5KSA8PCA0KSArIDE1XSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgICAgIGEgPSBIWzBdO1xuICAgICAgICBiID0gSFsxXTtcbiAgICAgICAgYyA9IEhbMl07XG4gICAgICAgIGQgPSBIWzNdO1xuICAgICAgICBlID0gSFs0XTtcblxuICAgICAgICBmb3IgKHQgPSAwOyB0IDwgODA7IHQgKz0gMSkge1xuICAgICAgICAgIGlmICh0IDwgMTYpIHtcbiAgICAgICAgICAgIFdbdF0gPSBtZXNzYWdlW3QgKyBpXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgV1t0XSA9IHJvdGwoV1t0IC0gM10gXiBXW3QgLSA4XSBeIFdbdCAtIDE0XSBeIFdbdCAtIDE2XSwgMSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHQgPCAyMCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBjaChiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0IDwgNDApIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgcGFyaXR5KGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPCA2MCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBtYWooYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIHBhcml0eShiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZSA9IGQ7XG4gICAgICAgICAgZCA9IGM7XG4gICAgICAgICAgYyA9IHJvdGwoYiwgMzApO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBUO1xuICAgICAgICB9XG5cbiAgICAgICAgSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcbiAgICAgICAgSFsxXSA9IHNhZmVBZGRfMihiLCBIWzFdKTtcbiAgICAgICAgSFsyXSA9IHNhZmVBZGRfMihjLCBIWzJdKTtcbiAgICAgICAgSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcbiAgICAgICAgSFs0XSA9IHNhZmVBZGRfMihlLCBIWzRdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEg7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGVzaXJlZCBTSEEtMiBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gVGhlIGJpbmFyeSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHRvIGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gVGhlIG51bWJlciBvZiBiaXRzIGluIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEtMiB2YXJpYW50XG4gICAgICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMiBoYXNoIG9mIG1lc3NhZ2VcbiAgICAgKi9cbiAgICBjb3JlU0hBMiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIG1lc3NhZ2VMZW4sIHZhcmlhbnQpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBUMSwgVDIsIEgsIG51bVJvdW5kcywgbGVuZ3RoUG9zaXRpb24sIGksIHQsXG4gICAgICAgIGJpbmFyeVN0cmluZ0luYywgYmluYXJ5U3RyaW5nTXVsdCwgc2FmZUFkZF8yLCBzYWZlQWRkXzQsIHNhZmVBZGRfNSxcbiAgICAgICAgZ2FtbWEwLCBnYW1tYTEsIHNpZ21hMCwgc2lnbWExLCBjaCwgbWFqLCBJbnQsIEssIFcgPSBbXSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoO1xuXG4gICAgICAvKiBTZXQgdXAgdGhlIHZhcmlvdXMgZnVuY3Rpb24gaGFuZGxlcyBhbmQgdmFyaWFibGUgZm9yIHRoZSBzcGVjaWZpYyBcbiAgICAgICAqIHZhcmlhbnQgKi9cbiAgICAgIGlmICh2YXJpYW50ID09PSBcIlNIQS0yMjRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS0yNTZcIikge1xuICAgICAgICAvKiAzMi1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA2NDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTU7XG4gICAgICAgIGJpbmFyeVN0cmluZ0luYyA9IDE2O1xuICAgICAgICBiaW5hcnlTdHJpbmdNdWx0ID0gMTtcbiAgICAgICAgSW50ID0gTnVtYmVyO1xuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzI7XG4gICAgICAgIHNhZmVBZGRfNCA9IHNhZmVBZGRfMzJfNDtcbiAgICAgICAgc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81O1xuICAgICAgICBnYW1tYTAgPSBnYW1tYTBfMzI7XG4gICAgICAgIGdhbW1hMSA9IGdhbW1hMV8zMjtcbiAgICAgICAgc2lnbWEwID0gc2lnbWEwXzMyO1xuICAgICAgICBzaWdtYTEgPSBzaWdtYTFfMzI7XG4gICAgICAgIG1haiA9IG1hal8zMjtcbiAgICAgICAgY2ggPSBjaF8zMjtcbiAgICAgICAgSyA9IFtcbiAgICAgICAgICAgIDB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsXG4gICAgICAgICAgICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAgICAgICAgICAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgICAgICAgICAgIDB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsXG4gICAgICAgICAgICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAgICAgICAgICAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgICAgICAgICAgIDB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsXG4gICAgICAgICAgICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAgICAgICAgICAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgICAgICAgICAgIDB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsXG4gICAgICAgICAgICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAgICAgICAgICAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgICAgICAgICAgIDB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsXG4gICAgICAgICAgICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAgICAgICAgICAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgICAgICAgICAgIDB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjJcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIpIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0XG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLFxuICAgICAgICAgICAgICAweDUxMEU1MjdGLCAweDlCMDU2ODhDLCAweDFGODNEOUFCLCAweDVCRTBDRDE5XG4gICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh2YXJpYW50ID09PSBcIlNIQS0zODRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS01MTJcIikge1xuICAgICAgICAvKiA2NC1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA4MDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgMTI4KSA+PiAxMCkgPDwgNSkgKyAzMTtcbiAgICAgICAgYmluYXJ5U3RyaW5nSW5jID0gMzI7XG4gICAgICAgIGJpbmFyeVN0cmluZ011bHQgPSAyO1xuICAgICAgICBJbnQgPSBJbnRfNjQ7XG4gICAgICAgIHNhZmVBZGRfMiA9IHNhZmVBZGRfNjRfMjtcbiAgICAgICAgc2FmZUFkZF80ID0gc2FmZUFkZF82NF80O1xuICAgICAgICBzYWZlQWRkXzUgPSBzYWZlQWRkXzY0XzU7XG4gICAgICAgIGdhbW1hMCA9IGdhbW1hMF82NDtcbiAgICAgICAgZ2FtbWExID0gZ2FtbWExXzY0O1xuICAgICAgICBzaWdtYTAgPSBzaWdtYTBfNjQ7XG4gICAgICAgIHNpZ21hMSA9IHNpZ21hMV82NDtcbiAgICAgICAgbWFqID0gbWFqXzY0O1xuICAgICAgICBjaCA9IGNoXzY0O1xuXG4gICAgICAgIEsgPSBbXG4gICAgICAgICAgICBuZXcgSW50KDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIpLCBuZXcgSW50KDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLFxuICAgICAgICAgICAgbmV3IEludCgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgbmV3IEludCgweGU5YjVkYmE1LCAweDgxODlkYmJjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCksIG5ldyBJbnQoMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIpLCBuZXcgSW50KDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLFxuICAgICAgICAgICAgbmV3IEludCgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgbmV3IEludCgweDEyODM1YjAxLCAweDQ1NzA2ZmJlKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyNDMxODViZSwgMHg0ZWU0YjI4YyksIG5ldyBJbnQoMHg1NTBjN2RjMywgMHhkNWZmYjRlMiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYpLCBuZXcgSW50KDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLFxuICAgICAgICAgICAgbmV3IEludCgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgbmV3IEludCgweGMxOWJmMTc0LCAweGNmNjkyNjk0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhlNDliNjljMSwgMHg5ZWYxNGFkMiksIG5ldyBJbnQoMHhlZmJlNDc4NiwgMHgzODRmMjVlMyksXG4gICAgICAgICAgICBuZXcgSW50KDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUpLCBuZXcgSW50KDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLFxuICAgICAgICAgICAgbmV3IEludCgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgbmV3IEludCgweDRhNzQ4NGFhLCAweDZlYTZlNDgzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCksIG5ldyBJbnQoMHg3NmY5ODhkYSwgMHg4MzExNTNiNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIpLCBuZXcgSW50KDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLFxuICAgICAgICAgICAgbmV3IEludCgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgbmV3IEludCgweGJmNTk3ZmM3LCAweGJlZWYwZWU0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjNmUwMGJmMywgMHgzZGE4OGZjMiksIG5ldyBJbnQoMHhkNWE3OTE0NywgMHg5MzBhYTcyNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYpLCBuZXcgSW50KDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLFxuICAgICAgICAgICAgbmV3IEludCgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgbmV3IEludCgweDJlMWIyMTM4LCAweDVjMjZjOTI2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCksIG5ldyBJbnQoMHg1MzM4MGQxMywgMHg5ZDk1YjNkZiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NjUwYTczNTQsIDB4OGJhZjYzZGUpLCBuZXcgSW50KDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLFxuICAgICAgICAgICAgbmV3IEludCgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgbmV3IEludCgweDkyNzIyYzg1LCAweDE0ODIzNTNiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCksIG5ldyBJbnQoMHhhODFhNjY0YiwgMHhiYzQyMzAwMSksXG4gICAgICAgICAgICBuZXcgSW50KDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEpLCBuZXcgSW50KDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLFxuICAgICAgICAgICAgbmV3IEludCgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgbmV3IEludCgweGQ2OTkwNjI0LCAweDU1NjVhOTEwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSksIG5ldyBJbnQoMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgpLCBuZXcgSW50KDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgbmV3IEludCgweDM0YjBiY2I1LCAweGUxOWI0OGE4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTFjMGNiMywgMHhjNWM5NWE2MyksIG5ldyBJbnQoMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMpLCBuZXcgSW50KDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgbmV3IEludCgweDc4YTU2MzZmLCAweDQzMTcyZjYwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiksIG5ldyBJbnQoMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgpLCBuZXcgSW50KDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLFxuICAgICAgICAgICAgbmV3IEludCgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgbmV3IEludCgweGM2NzE3OGYyLCAweGUzNzI1MzJiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjYTI3M2VjZSwgMHhlYTI2NjE5YyksIG5ldyBJbnQoMHhkMTg2YjhjNywgMHgyMWMwYzIwNyksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUpLCBuZXcgSW50KDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLFxuICAgICAgICAgICAgbmV3IEludCgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgbmV3IEludCgweDBhNjM3ZGM1LCAweGEyYzg5OGE2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSksIG5ldyBJbnQoMHgxYjcxMGIzNSwgMHgxMzFjNDcxYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQpLCBuZXcgSW50KDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgbmV3IEludCgweDQzMWQ2N2M0LCAweDljMTAwZDRjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiksIG5ldyBJbnQoMHg1OTdmMjk5YywgMHhmYzY1N2UyYSksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMpLCBuZXcgSW50KDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiKSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgbmV3IEludCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IEludCgweDA2MjlhMjkyYSwgMHgzNjdjZDUwNyksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg5MTU5MDE1YSwgMHgzMDcwZGQxNyksIG5ldyBJbnQoMHgwMTUyZmVjZDgsIDB4ZjcwZTU5MzkpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4NjczMzI2NjcsIDB4ZmZjMDBiMzEpLCBuZXcgSW50KDB4OThlYjQ0YTg3LCAweDY4NTgxNTExKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IEludCgweDA0N2I1NDgxZCwgMHhiZWZhNGZhNClcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCksIG5ldyBJbnQoMHhiYjY3YWU4NSwgMHg4NGNhYTczYiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYiksIG5ldyBJbnQoMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBJbnQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YiksIG5ldyBJbnQoMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSlcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuICAgICAgbWVzc2FnZVttZXNzYWdlTGVuID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbWVzc2FnZUxlbiAlIDMyKTtcbiAgICAgIC8qIEFwcGVuZCBsZW5ndGggb2YgYmluYXJ5IHN0cmluZyBpbiB0aGUgcG9zaXRpb24gc3VjaCB0aGF0IHRoZSBuZXdcbiAgICAgICAqIGxlbmd0aCBpcyBjb3JyZWN0ICovXG4gICAgICBtZXNzYWdlW2xlbmd0aFBvc2l0aW9uXSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IGJpbmFyeVN0cmluZ0luYykge1xuICAgICAgICBhID0gSFswXTtcbiAgICAgICAgYiA9IEhbMV07XG4gICAgICAgIGMgPSBIWzJdO1xuICAgICAgICBkID0gSFszXTtcbiAgICAgICAgZSA9IEhbNF07XG4gICAgICAgIGYgPSBIWzVdO1xuICAgICAgICBnID0gSFs2XTtcbiAgICAgICAgaCA9IEhbN107XG5cbiAgICAgICAgZm9yICh0ID0gMDsgdCA8IG51bVJvdW5kczsgdCArPSAxKSB7XG4gICAgICAgICAgaWYgKHQgPCAxNikge1xuICAgICAgICAgICAgLyogQml0IG9mIGEgaGFjayAtIGZvciAzMi1iaXQsIHRoZSBzZWNvbmQgdGVybSBpcyBpZ25vcmVkICovXG4gICAgICAgICAgICBXW3RdID0gbmV3IEludChtZXNzYWdlW3QgKiBiaW5hcnlTdHJpbmdNdWx0ICsgaV0sXG4gICAgICAgICAgICAgIG1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpICsgMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBXW3RdID0gc2FmZUFkZF80KFxuICAgICAgICAgICAgICBnYW1tYTEoV1t0IC0gMl0pLCBXW3QgLSA3XSxcbiAgICAgICAgICAgICAgZ2FtbWEwKFdbdCAtIDE1XSksIFdbdCAtIDE2XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgVDEgPSBzYWZlQWRkXzUoaCwgc2lnbWExKGUpLCBjaChlLCBmLCBnKSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgVDIgPSBzYWZlQWRkXzIoc2lnbWEwKGEpLCBtYWooYSwgYiwgYykpO1xuICAgICAgICAgIGggPSBnO1xuICAgICAgICAgIGcgPSBmO1xuICAgICAgICAgIGYgPSBlO1xuICAgICAgICAgIGUgPSBzYWZlQWRkXzIoZCwgVDEpO1xuICAgICAgICAgIGQgPSBjO1xuICAgICAgICAgIGMgPSBiO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBzYWZlQWRkXzIoVDEsIFQyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIEhbMF0gPSBzYWZlQWRkXzIoYSwgSFswXSk7XG4gICAgICAgIEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG4gICAgICAgIEhbMl0gPSBzYWZlQWRkXzIoYywgSFsyXSk7XG4gICAgICAgIEhbM10gPSBzYWZlQWRkXzIoZCwgSFszXSk7XG4gICAgICAgIEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG4gICAgICAgIEhbNV0gPSBzYWZlQWRkXzIoZiwgSFs1XSk7XG4gICAgICAgIEhbNl0gPSBzYWZlQWRkXzIoZywgSFs2XSk7XG4gICAgICAgIEhbN10gPSBzYWZlQWRkXzIoaCwgSFs3XSk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBIWzBdLCBIWzFdLCBIWzJdLCBIWzNdLFxuICAgICAgICAgICAgSFs0XSwgSFs1XSwgSFs2XV07XG4gICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgcmV0dXJuIEg7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcl07XG4gICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNl0uaGlnaE9yZGVyLCBIWzZdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs3XS5oaWdoT3JkZXIsIEhbN10ubG93T3JkZXJdO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8qIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHJlYWNoZWQgKi9cbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICoganNTSEEgaXMgdGhlIHdvcmtob3JzZSBvZiB0aGUgbGlicmFyeS4gIEluc3RhbnRpYXRlIGl0IHdpdGggdGhlIHN0cmluZyB0b1xuICAgICAqIGJlIGhhc2hlZCBhcyB0aGUgcGFyYW1ldGVyXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3JjU3RyaW5nIFRoZSBzdHJpbmcgdG8gYmUgaGFzaGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Ygc3JjU3RyaW5nLCBBU0NJSSBvciBIRVhcbiAgICAgKi9cbiAgICBqc1NIQSA9IGZ1bmN0aW9uKHNyY1N0cmluZywgaW5wdXRGb3JtYXQpIHtcblxuICAgICAgdGhpcy5zaGExID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjI0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjU2ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMzg0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhNTEyID0gbnVsbDtcblxuICAgICAgdGhpcy5zdHJCaW5MZW4gPSBudWxsO1xuICAgICAgdGhpcy5zdHJUb0hhc2ggPSBudWxsO1xuXG4gICAgICAvKiBDb252ZXJ0IHRoZSBpbnB1dCBzdHJpbmcgaW50byB0aGUgY29ycmVjdCB0eXBlICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgaWYgKDAgIT09IChzcmNTdHJpbmcubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJURVhUIE1VU1QgQkUgSU4gQllURSBJTkNSRU1FTlRTXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogNDtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBoZXgyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmICgoXCJBU0NJSVwiID09PSBpbnB1dEZvcm1hdCkgfHxcbiAgICAgICAgKCd1bmRlZmluZWQnID09PSB0eXBlb2YoaW5wdXRGb3JtYXQpKSkge1xuICAgICAgICB0aGlzLnN0ckJpbkxlbiA9IHNyY1N0cmluZy5sZW5ndGggKiBjaGFyU2l6ZTtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBzdHIyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBURVhUIElOUFVUIFRZUEVcIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gIGpzU0hBLnByb3RvdHlwZSA9IHtcbiAgICAvKlxuICAgICAqIFJldHVybnMgdGhlIGRlc2lyZWQgU0hBIGhhc2ggb2YgdGhlIHN0cmluZyBzcGVjaWZpZWQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBIHZhcmlhbnQgKFNIQS0xLCBTSEEtMjI0LFxuICAgICAqXHQgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0IFRoZSBkZXNpcmVkIG91dHB1dCBmb3JtYXR0aW5nIChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhhc2g6IGZ1bmN0aW9uKHZhcmlhbnQsIGZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMgPSBudWxsLFxuICAgICAgICBtZXNzYWdlID0gdGhpcy5zdHJUb0hhc2guc2xpY2UoKTtcblxuICAgICAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHZhcmlhbnQpIHtcbiAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMSkge1xuICAgICAgICAgICAgdGhpcy5zaGExID0gY29yZVNIQTEobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTEpO1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTIyNCkge1xuICAgICAgICAgICAgdGhpcy5zaGEyMjQgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMjI0KTtcbiAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGEyNTYpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMjU2ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTI1Nik7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMzg0KSB7XG4gICAgICAgICAgICB0aGlzLnNoYTM4NCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEzODQpO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTUxMikge1xuICAgICAgICAgICAgdGhpcy5zaGE1MTIgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhNTEyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJIQVNIIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBITUFDIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cbiAgICAgKiB1c2luZyB0aGUga2V5IGFuZCB2YXJpYW50IHBhcmFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUga2V5IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBITUFDXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Yga2V5LCBBU0NJSSBvciBIRVhcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEgdmFyaWFudCAoU0hBLTEsIFNIQS0yMjQsXG4gICAgICpcdCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRGb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmdcbiAgICAgKlx0IChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhNQUM6IGZ1bmN0aW9uKGtleSwgaW5wdXRGb3JtYXQsIHZhcmlhbnQsIG91dHB1dEZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMsIGtleVRvVXNlLCBibG9ja0J5dGVTaXplLCBibG9ja0JpdFNpemUsIGksXG4gICAgICAgIHJldFZhbCwgbGFzdEFycmF5SW5kZXgsIGtleUJpbkxlbiwgaGFzaEJpdFNpemUsXG4gICAgICAgIGtleVdpdGhJUGFkID0gW10sXG4gICAgICAgIGtleVdpdGhPUGFkID0gW107XG5cbiAgICAgIC8qIFZhbGlkYXRlIHRoZSBvdXRwdXQgZm9ybWF0IHNlbGVjdGlvbiAqL1xuICAgICAgc3dpdGNoIChvdXRwdXRGb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSB0aGUgaGFzaCB2YXJpYW50IHNlbGVjdGlvbiBhbmQgc2V0IG5lZWRlZCB2YXJpYWJsZXMgKi9cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gNjQ7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAxNjA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtMjI0XCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDY0O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMjI0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSA2NDtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDI1NjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gMTI4O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMzg0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSAxMjg7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSA1MTI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiSEFTSCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSBpbnB1dCBmb3JtYXQgc2VsZWN0aW9uICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgLyogTmliYmxlcyBtdXN0IGNvbWUgaW4gcGFpcnMgKi9cbiAgICAgICAgaWYgKDAgIT09IChrZXkubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJLRVkgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFNcIjtcbiAgICAgICAgfVxuICAgICAgICBrZXlUb1VzZSA9IGhleDJiaW5iKGtleSk7XG4gICAgICAgIGtleUJpbkxlbiA9IGtleS5sZW5ndGggKiA0O1xuICAgICAgfSBlbHNlIGlmIChcIkFTQ0lJXCIgPT09IGlucHV0Rm9ybWF0KSB7XG4gICAgICAgIGtleVRvVXNlID0gc3RyMmJpbmIoa2V5KTtcbiAgICAgICAga2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIGNoYXJTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBLRVkgSU5QVVQgVFlQRVwiO1xuICAgICAgfVxuXG4gICAgICAvKiBUaGVzZSBhcmUgdXNlZCBtdWx0aXBsZSB0aW1lcywgY2FsY3VsYXRlIGFuZCBzdG9yZSB0aGVtICovXG4gICAgICBibG9ja0JpdFNpemUgPSBibG9ja0J5dGVTaXplICogODtcbiAgICAgIGxhc3RBcnJheUluZGV4ID0gKGJsb2NrQnl0ZVNpemUgLyA0KSAtIDE7XG5cbiAgICAgIC8qIEZpZ3VyZSBvdXQgd2hhdCB0byBkbyB3aXRoIHRoZSBrZXkgYmFzZWQgb24gaXRzIHNpemUgcmVsYXRpdmUgdG9cbiAgICAgICAqIHRoZSBoYXNoJ3MgYmxvY2sgc2l6ZSAqL1xuICAgICAgaWYgKGJsb2NrQnl0ZVNpemUgPCAoa2V5QmluTGVuIC8gOCkpIHtcbiAgICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICAgIGtleVRvVXNlID0gY29yZVNIQTEoa2V5VG9Vc2UsIGtleUJpbkxlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5VG9Vc2UgPSBjb3JlU0hBMihrZXlUb1VzZSwga2V5QmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgfVxuICAgICAgICAvKiBGb3IgYWxsIHZhcmlhbnRzLCB0aGUgYmxvY2sgc2l6ZSBpcyBiaWdnZXIgdGhhbiB0aGUgb3V0cHV0XG4gICAgICAgICAqIHNpemUgc28gdGhlcmUgd2lsbCBuZXZlciBiZSBhIHVzZWZ1bCBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH0gZWxzZSBpZiAoYmxvY2tCeXRlU2l6ZSA+IChrZXlCaW5MZW4gLyA4KSkge1xuICAgICAgICAvKiBJZiB0aGUgYmxvY2tCeXRlU2l6ZSBpcyBncmVhdGVyIHRoYW4gdGhlIGtleSBsZW5ndGgsIHRoZXJlXG4gICAgICAgICAqIHdpbGwgYWx3YXlzIGJlIGF0IExFQVNUIG9uZSBcInVzZWxlc3NcIiBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH1cblxuICAgICAgLyogQ3JlYXRlIGlwYWQgYW5kIG9wYWQgKi9cbiAgICAgIGZvciAoaSA9IDA7IGkgPD0gbGFzdEFycmF5SW5kZXg7IGkgKz0gMSkge1xuICAgICAgICBrZXlXaXRoSVBhZFtpXSA9IGtleVRvVXNlW2ldIF4gMHgzNjM2MzYzNjtcbiAgICAgICAga2V5V2l0aE9QYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4NUM1QzVDNUM7XG4gICAgICB9XG5cbiAgICAgIC8qIENhbGN1bGF0ZSB0aGUgSE1BQyAqL1xuICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMShcbiAgICAgICAgICBrZXlXaXRoSVBhZC5jb25jYXQodGhpcy5zdHJUb0hhc2gpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIHRoaXMuc3RyQmluTGVuKTtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTEoXG4gICAgICAgICAga2V5V2l0aE9QYWQuY29uY2F0KHJldFZhbCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTIoXG4gICAgICAgICAga2V5V2l0aElQYWQuY29uY2F0KHRoaXMuc3RyVG9IYXNoKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEEyKFxuICAgICAgICAgIGtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIGhhc2hCaXRTaXplLCB2YXJpYW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIChmb3JtYXRGdW5jKHJldFZhbCkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4ganNTSEE7XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hhMTogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTFcIiwgXCJBU0NJSVwiKTtcbiAgfSxcbiAgc2hhMjI0OiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMjI0XCIsIFwiQVNDSUlcIik7XG4gIH0sXG4gIHNoYTI1NjogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTI1NlwiLCBcIkFTQ0lJXCIpO1xuICB9LFxuICBzaGEzODQ6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0zODRcIiwgXCJBU0NJSVwiKTtcblxuICB9LFxuICBzaGE1MTI6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS01MTJcIiwgXCJBU0NJSVwiKTtcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNpcGhlcjogcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgaGFzaDogcmVxdWlyZSgnLi9oYXNoJyksXG4gIGNmYjogcmVxdWlyZSgnLi9jZmIuanMnKSxcbiAgcHVibGljS2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgc2lnbmF0dXJlOiByZXF1aXJlKCcuL3NpZ25hdHVyZS5qcycpLFxuICByYW5kb206IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIHBrY3MxOiByZXF1aXJlKCcuL3BrY3MxLmpzJylcblxufVxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8uanMnKTtcblxuZm9yICh2YXIgaSBpbiBjcnlwdG8pXG4gIG1vZHVsZS5leHBvcnRzW2ldID0gY3J5cHRvW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgY3J5cHRvL3BrY3MxICovXG5cbi8qKlxuICogQVNOMSBvYmplY3QgaWRlbnRpZmllcnMgZm9yIGhhc2hlcyAoU2VlIFJGQzQ4ODAgNS4yLjIpXG4gKi9cbmhhc2hfaGVhZGVycyA9IG5ldyBBcnJheSgpO1xuaGFzaF9oZWFkZXJzWzFdID0gWzB4MzAsIDB4MjAsIDB4MzAsIDB4MGMsIDB4MDYsIDB4MDgsIDB4MmEsIDB4ODYsIDB4NDgsIDB4ODYsIDB4ZjcsIDB4MGQsIDB4MDIsIDB4MDUsIDB4MDUsIDB4MDAsIDB4MDQsXG4gICAgMHgxMFxuXTtcbmhhc2hfaGVhZGVyc1szXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJCLCAweDI0LCAweDAzLCAweDAyLCAweDAxLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1syXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJiLCAweDBlLCAweDAzLCAweDAyLCAweDFhLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1s4XSA9IFsweDMwLCAweDMxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAxLCAweDA1LCAweDAwLFxuICAgIDB4MDQsIDB4MjBcbl07XG5oYXNoX2hlYWRlcnNbOV0gPSBbMHgzMCwgMHg0MSwgMHgzMCwgMHgwZCwgMHgwNiwgMHgwOSwgMHg2MCwgMHg4NiwgMHg0OCwgMHgwMSwgMHg2NSwgMHgwMywgMHgwNCwgMHgwMiwgMHgwMiwgMHgwNSwgMHgwMCxcbiAgICAweDA0LCAweDMwXG5dO1xuaGFzaF9oZWFkZXJzWzEwXSA9IFsweDMwLCAweDUxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAzLCAweDA1LFxuICAgIDB4MDAsIDB4MDQsIDB4NDBcbl07XG5oYXNoX2hlYWRlcnNbMTFdID0gWzB4MzAsIDB4MzEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDQsIDB4MDUsXG4gICAgMHgwMCwgMHgwNCwgMHgxQ1xuXTtcblxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi9yYW5kb20uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIGhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVtZToge1xuICAgIC8qKlxuICAgICAqIGNyZWF0ZSBhIEVNRS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMSlcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIHBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCB0byB0aGUgcmVzdWx0aW5nIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IEVNRS1QS0NTMSBwYWRkZWQgbWVzc2FnZVxuICAgICAqL1xuICAgIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZSwgbGVuZ3RoKSB7XG4gICAgICBpZiAobWVzc2FnZS5sZW5ndGggPiBsZW5ndGggLSAxMSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDIpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGggLSBtZXNzYWdlLmxlbmd0aCAtIDM7IGkrKykge1xuICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShyYW5kb20uZ2V0UHNldWRvUmFuZG9tKDEsIDI1NSkpO1xuICAgICAgfVxuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICByZXN1bHQgKz0gbWVzc2FnZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGRlY29kZXMgYSBFTUUtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjIpXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgRU1FLVBLQ1MxIHBhZGRlZCBtZXNzYWdlXG4gICAgICogQHJldHVybiB7U3RyaW5nfSBkZWNvZGVkIG1lc3NhZ2UgXG4gICAgICovXG4gICAgZGVjb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW4pIHtcbiAgICAgIGlmIChtZXNzYWdlLmxlbmd0aCA8IGxlbilcbiAgICAgICAgbWVzc2FnZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCkgKyBtZXNzYWdlO1xuICAgICAgaWYgKG1lc3NhZ2UubGVuZ3RoIDwgMTIgfHwgbWVzc2FnZS5jaGFyQ29kZUF0KDApICE9IDAgfHwgbWVzc2FnZS5jaGFyQ29kZUF0KDEpICE9IDIpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIHZhciBpID0gMjtcbiAgICAgIHdoaWxlIChtZXNzYWdlLmNoYXJDb2RlQXQoaSkgIT0gMCAmJiBtZXNzYWdlLmxlbmd0aCA+IGkpXG4gICAgICAgIGkrKztcbiAgICAgIHJldHVybiBtZXNzYWdlLnN1YnN0cmluZyhpICsgMSwgbWVzc2FnZS5sZW5ndGgpO1xuICAgIH0sXG4gIH0sXG5cbiAgZW1zYToge1xuXG4gICAgLyoqXG4gICAgICogY3JlYXRlIGEgRU1TQS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMylcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSB1c2VkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBoYXNoZWRcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleWxlbmd0aCBLZXkgc2l6ZSBvZiB0aGUgcHVibGljIG1waSBpbiBieXRlc1xuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IEhhc2hjb2RlIHdpdGggcGtjczFwYWRkaW5nIGFzIHN0cmluZ1xuICAgICAqL1xuICAgIGVuY29kZTogZnVuY3Rpb24oYWxnbywgZGF0YSwga2V5bGVuZ3RoKSB7XG4gICAgICB2YXIgZGF0YTIgPSBcIlwiO1xuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcbiAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IChrZXlsZW5ndGggLSBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoIC0gMyAtXG4gICAgICAgIGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpOyBpKyspXG5cbiAgICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweGZmKTtcblxuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoOyBpKyspXG4gICAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaF9oZWFkZXJzW2FsZ29dW2ldKTtcblxuICAgICAgZGF0YTIgKz0gaGFzaC5kaWdlc3QoYWxnbywgZGF0YSk7XG4gICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGRhdGEyKSwgMTYpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBleHRyYWN0IHRoZSBoYXNoIG91dCBvZiBhbiBFTVNBLVBLQ1MxLXYxLjUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKSBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBIYXNoIGluIHBrY3MxIGVuY29kaW5nXG4gICAgICogQHJldHVybnMge1N0cmluZ30gVGhlIGhhc2ggYXMgc3RyaW5nXG4gICAgICovXG4gICAgZGVjb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgICB2YXIgaSA9IDA7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KDApID09IDApIGkrKztcbiAgICAgIGVsc2UgaWYgKGRhdGEuY2hhckNvZGVBdCgwKSAhPSAxKSByZXR1cm4gLTE7XG4gICAgICBlbHNlIGkrKztcblxuICAgICAgd2hpbGUgKGRhdGEuY2hhckNvZGVBdChpKSA9PSAweEZGKSBpKys7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KGkrKykgIT0gMCkgcmV0dXJuIC0xO1xuICAgICAgdmFyIGogPSAwO1xuICAgICAgZm9yIChqID0gMDsgaiA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggJiYgaiArIGkgPCBkYXRhLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoaiArIGkpICE9IGhhc2hfaGVhZGVyc1thbGdvXVtqXSkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgaSArPSBqO1xuICAgICAgaWYgKGRhdGEuc3Vic3RyaW5nKGkpLmxlbmd0aCA8IGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpIHJldHVybiAtMTtcbiAgICAgIHJldHVybiBkYXRhLnN1YnN0cmluZyhpKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gQSBEaWdpdGFsIHNpZ25hdHVyZSBhbGdvcml0aG0gaW1wbGVtZW50YXRpb25cblxuLyoqIEBtb2R1bGUgY3J5cHRvL3B1YmxpY19rZXkvZHNhICovXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyksXG4gIHJhbmRvbSA9IHJlcXVpcmUoJy4uL3JhbmRvbS5qcycpLFxuICBoYXNoTW9kdWxlID0gcmVxdWlyZSgnLi4vaGFzaCcpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG5mdW5jdGlvbiBEU0EoKSB7XG4gIC8vIHMxID0gKChnKipzKSBtb2QgcCkgbW9kIHFcbiAgLy8gczEgPSAoKHMqKi0xKSooc2hhLTEobSkrKHMxKngpIG1vZCBxKVxuICBmdW5jdGlvbiBzaWduKGhhc2hhbGdvLCBtLCBnLCBwLCBxLCB4KSB7XG4gICAgLy8gSWYgdGhlIG91dHB1dCBzaXplIG9mIHRoZSBjaG9zZW4gaGFzaCBpcyBsYXJnZXIgdGhhbiB0aGUgbnVtYmVyIG9mXG4gICAgLy8gYml0cyBvZiBxLCB0aGUgaGFzaCByZXN1bHQgaXMgdHJ1bmNhdGVkIHRvIGZpdCBieSB0YWtpbmcgdGhlIG51bWJlclxuICAgIC8vIG9mIGxlZnRtb3N0IGJpdHMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBiaXRzIG9mIHEuICBUaGlzIChwb3NzaWJseVxuICAgIC8vIHRydW5jYXRlZCkgaGFzaCBmdW5jdGlvbiByZXN1bHQgaXMgdHJlYXRlZCBhcyBhIG51bWJlciBhbmQgdXNlZFxuICAgIC8vIGRpcmVjdGx5IGluIHRoZSBEU0Egc2lnbmF0dXJlIGFsZ29yaXRobS5cbiAgICB2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhoYXNoTW9kdWxlLmRpZ2VzdChoYXNoYWxnbywgbSksIHEuYml0TGVuZ3RoKCkpO1xuICAgIHZhciBoYXNoID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGhhc2hlZF9kYXRhKSwgMTYpO1xuICAgIHZhciBrID0gcmFuZG9tLmdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKEJpZ0ludGVnZXIuT05FLmFkZChCaWdJbnRlZ2VyLk9ORSksIHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTtcbiAgICB2YXIgczEgPSAoZy5tb2RQb3coaywgcCkpLm1vZChxKTtcbiAgICB2YXIgczIgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkoczEpKSkpLm1vZChxKTtcbiAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG4gICAgcmVzdWx0WzBdID0gczEudG9NUEkoKTtcbiAgICByZXN1bHRbMV0gPSBzMi50b01QSSgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3RfaGFzaF9hbGdvcml0aG0ocSkge1xuICAgIHZhciB1c2Vyc2V0dGluZyA9IG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgLypcbiAgICAgKiAxMDI0LWJpdCBrZXksIDE2MC1iaXQgcSwgU0hBLTEsIFNIQS0yMjQsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqIDIwNDgtYml0IGtleSwgMjI0LWJpdCBxLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKiAyMDQ4LWJpdCBrZXksIDI1Ni1iaXQgcSwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICogMzA3Mi1iaXQga2V5LCAyNTYtYml0IHEsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqL1xuICAgIHN3aXRjaCAoTWF0aC5yb3VuZChxLmJpdExlbmd0aCgpIC8gOCkpIHtcbiAgICAgIGNhc2UgMjA6XG4gICAgICAgIC8vIDEwMjQgYml0XG4gICAgICAgIGlmICh1c2Vyc2V0dGluZyAhPSAyICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPiAxMSAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nICE9IDEwICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPCA4KVxuICAgICAgICAgIHJldHVybiAyOyAvLyBwcmVmZXIgc2hhMVxuICAgICAgICByZXR1cm4gdXNlcnNldHRpbmc7XG4gICAgICBjYXNlIDI4OlxuICAgICAgICAvLyAyMDQ4IGJpdFxuICAgICAgICBpZiAodXNlcnNldHRpbmcgPiAxMSAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nIDwgOClcbiAgICAgICAgICByZXR1cm4gMTE7XG4gICAgICAgIHJldHVybiB1c2Vyc2V0dGluZztcbiAgICAgIGNhc2UgMzI6XG4gICAgICAgIC8vIDQwOTYgYml0IC8vIHByZWZlciBzaGEyMjRcbiAgICAgICAgaWYgKHVzZXJzZXR0aW5nID4gMTAgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA8IDgpXG4gICAgICAgICAgcmV0dXJuIDg7IC8vIHByZWZlciBzaGEyNTZcbiAgICAgICAgcmV0dXJuIHVzZXJzZXR0aW5nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIkRTQSBzZWxlY3QgaGFzaCBhbGdvcml0aG06IHJldHVybmluZyBudWxsIGZvciBhbiB1bmtub3duIGxlbmd0aCBvZiBxXCIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgIH1cbiAgfVxuICB0aGlzLnNlbGVjdF9oYXNoX2FsZ29yaXRobSA9IHNlbGVjdF9oYXNoX2FsZ29yaXRobTtcblxuICBmdW5jdGlvbiB2ZXJpZnkoaGFzaGFsZ28sIHMxLCBzMiwgbSwgcCwgcSwgZywgeSkge1xuICAgIHZhciBoYXNoZWRfZGF0YSA9IHV0aWwuZ2V0TGVmdE5CaXRzKGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hhbGdvLCBtKSwgcS5iaXRMZW5ndGgoKSk7XG4gICAgdmFyIGhhc2ggPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoaGFzaGVkX2RhdGEpLCAxNik7XG4gICAgaWYgKEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczEpID4gMCB8fFxuICAgICAgczEuY29tcGFyZVRvKHEpID4gMCB8fFxuICAgICAgQmlnSW50ZWdlci5aRVJPLmNvbXBhcmVUbyhzMikgPiAwIHx8XG4gICAgICBzMi5jb21wYXJlVG8ocSkgPiAwKSB7XG4gICAgICB1dGlsLnByaW50X2RlYnVnKFwiaW52YWxpZCBEU0EgU2lnbmF0dXJlXCIpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciB3ID0gczIubW9kSW52ZXJzZShxKTtcbiAgICB2YXIgdTEgPSBoYXNoLm11bHRpcGx5KHcpLm1vZChxKTtcbiAgICB2YXIgdTIgPSBzMS5tdWx0aXBseSh3KS5tb2QocSk7XG4gICAgcmV0dXJuIGcubW9kUG93KHUxLCBwKS5tdWx0aXBseSh5Lm1vZFBvdyh1MiwgcCkpLm1vZChwKS5tb2QocSk7XG4gIH1cblxuICAvKlxuXHQgKiB1bnVzZWQgY29kZS4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIHN0YXJ0IHRvIHdyaXRlIGEga2V5IGdlbmVyYXRvclxuXHQgKiBmdW5jdGlvbi5cblx0XG5cdGZ1bmN0aW9uIGdlbmVyYXRlS2V5KGJpdGNvdW50KSB7XG5cdCAgICB2YXIgcWkgPSBuZXcgQmlnSW50ZWdlcihiaXRjb3VudCwgcHJpbWVDZW50ZXJpZSk7XG5cdCAgICB2YXIgcGkgPSBnZW5lcmF0ZVAocSwgNTEyKTtcblx0ICAgIHZhciBnaSA9IGdlbmVyYXRlRyhwLCBxLCBiaXRjb3VudCk7XG5cdCAgICB2YXIgeGk7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgeGkgPSBuZXcgQmlnSW50ZWdlcihxLmJpdENvdW50KCksIHJhbmQpO1xuXHQgICAgfSB3aGlsZSAoeC5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxICYmIHguY29tcGFyZVRvKHEpICE9IC0xKTtcblx0ICAgIHZhciB5aSA9IGcubW9kUG93KHgsIHApO1xuXHQgICAgcmV0dXJuIHt4OiB4aSwgcTogcWksIHA6IHBpLCBnOiBnaSwgeTogeWl9O1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVQKHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIGlmIChiaXRsZW5ndGggJSA2NCAhPSAwKSB7XG5cdCAgICBcdHJldHVybiBmYWxzZTtcblx0ICAgIH1cblx0ICAgIHZhciBwVGVtcDtcblx0ICAgIHZhciBwVGVtcDI7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgcFRlbXAgPSByYW5kb21mbihiaXRjb3VudCwgdHJ1ZSk7XG5cdCAgICAgICAgcFRlbXAyID0gcFRlbXAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgICAgIHBUZW1wID0gcFRlbXAuc3VidHJhY3QocFRlbXAyLnJlbWFpbmRlcihxKSk7XG5cdCAgICB9IHdoaWxlICghcFRlbXAuaXNQcm9iYWJsZVByaW1lKHByaW1lQ2VudGVyaWUpIHx8IHBUZW1wLmJpdExlbmd0aCgpICE9IGwpO1xuXHQgICAgcmV0dXJuIHBUZW1wO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBnZW5lcmF0ZUcocCwgcSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgdmFyIGF1eCA9IHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgdmFyIHBvdyA9IGF1eC5kaXZpZGUocSk7XG5cdCAgICB2YXIgZ1RlbXA7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgZ1RlbXAgPSByYW5kb21mbihiaXRsZW5ndGgpO1xuXHQgICAgfSB3aGlsZSAoZ1RlbXAuY29tcGFyZVRvKGF1eCkgIT0gLTEgJiYgZ1RlbXAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAxKTtcblx0ICAgIHJldHVybiBnVGVtcC5tb2RQb3cocG93LCBwKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlSyhxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICB2YXIgdGVtcEs7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgdGVtcEsgPSByYW5kb21mbihiaXRsZW5ndGgsIGZhbHNlKTtcblx0ICAgIH0gd2hpbGUgKHRlbXBLLmNvbXBhcmVUbyhxKSAhPSAtMSAmJiB0ZW1wSy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxKTtcblx0ICAgIHJldHVybiB0ZW1wSztcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUihxLHApIHtcblx0ICAgIGsgPSBnZW5lcmF0ZUsocSk7XG5cdCAgICB2YXIgciA9IGcubW9kUG93KGssIHApLm1vZChxKTtcblx0ICAgIHJldHVybiByO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVTKGhhc2hmbixrLHIsbSxxLHgpIHtcbiAgICAgICAgdmFyIGhhc2ggPSBoYXNoZm4obSk7XG4gICAgICAgIHMgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkocikpKSkubW9kKHEpO1xuXHQgICAgcmV0dXJuIHM7XG5cdH0gKi9cbiAgdGhpcy5zaWduID0gc2lnbjtcbiAgdGhpcy52ZXJpZnkgPSB2ZXJpZnk7XG4gIC8vIHRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZUtleTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEU0E7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIEVsR2FtYWwgaW1wbGVtZW50YXRpb25cblxuLyoqIEBtb2R1bGUgY3J5cHRvL3B1YmxpY19rZXkvZWxnYW1hbCAqL1xuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gRWxnYW1hbCgpIHtcblxuICBmdW5jdGlvbiBlbmNyeXB0KG0sIGcsIHAsIHkpIHtcbiAgICAvLyAgY2hvb3NlIGsgaW4gezIsLi4uLHAtMn1cbiAgICB2YXIgdHdvID0gQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKTtcbiAgICB2YXIgcE1pbnVzMiA9IHAuc3VidHJhY3QodHdvKTtcbiAgICB2YXIgayA9IHJhbmRvbS5nZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZSh0d28sIHBNaW51czIpO1xuICAgIGsgPSBrLm1vZChwTWludXMyKS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHZhciBjID0gW107XG4gICAgY1swXSA9IGcubW9kUG93KGssIHApO1xuICAgIGNbMV0gPSB5Lm1vZFBvdyhrLCBwKS5tdWx0aXBseShtKS5tb2QocCk7XG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICBmdW5jdGlvbiBkZWNyeXB0KGMxLCBjMiwgcCwgeCkge1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJFbGdhbWFsIERlY3J5cHQ6XFxuYzE6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzEudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwiYzI6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzIudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwicDpcIiArIHV0aWwuaGV4c3RyZHVtcChwLnRvTVBJKCkpICsgXCJcXG5cIiArXG4gICAgICBcIng6XCIgKyB1dGlsLmhleHN0cmR1bXAoeC50b01QSSgpKSk7XG4gICAgcmV0dXJuIChjMS5tb2RQb3coeCwgcCkubW9kSW52ZXJzZShwKSkubXVsdGlwbHkoYzIpLm1vZChwKTtcbiAgICAvL3ZhciBjID0gYzEucG93KHgpLm1vZEludmVyc2UocCk7IC8vIGMwXi1hIG1vZCBwXG4gICAgLy9yZXR1cm4gYy5tdWx0aXBseShjMikubW9kKHApO1xuICB9XG5cbiAgLy8gc2lnbmluZyBhbmQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiB1c2luZyBFbGdhbWFsIGlzIG5vdCByZXF1aXJlZCBieSBPcGVuUEdQLlxuICB0aGlzLmVuY3J5cHQgPSBlbmNyeXB0O1xuICB0aGlzLmRlY3J5cHQgPSBkZWNyeXB0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZ2FtYWw7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgcnNhOiByZXF1aXJlKCcuL3JzYS5qcycpLFxuICBlbGdhbWFsOiByZXF1aXJlKCcuL2VsZ2FtYWwuanMnKSxcbiAgZHNhOiByZXF1aXJlKCcuL2RzYS5qcycpXG59XG4iLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nXG4gKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbiAqIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvXG4gKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG9cbiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZVxuICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMtSVNcIiBBTkQgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgXG4gKiBFWFBSRVNTLCBJTVBMSUVEIE9SIE9USEVSV0lTRSwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIFxuICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgXG4gKlxuICogSU4gTk8gRVZFTlQgU0hBTEwgVE9NIFdVIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElOQ0lERU5UQUwsXG4gKiBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT0YgQU5ZIEtJTkQsIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVJcbiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0ZcbiAqIFRIRSBQT1NTSUJJTElUWSBPRiBEQU1BR0UsIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgQVJJU0lORyBPVVRcbiAqIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKlxuICogSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGFwcGxpZXM6XG4gKlxuICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2VcbiAqIGFuZCBkaXNjbGFpbWVyLlxuICovXG5cblxuLyoqIEBtb2R1bGUgY3J5cHRvL3B1YmxpY19rZXkvanNibiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gQmFzaWMgSmF2YVNjcmlwdCBCTiBsaWJyYXJ5IC0gc3Vic2V0IHVzZWZ1bCBmb3IgUlNBIGVuY3J5cHRpb24uXG5cbi8vIEJpdHMgcGVyIGRpZ2l0XG52YXIgZGJpdHM7XG5cbi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzXG52YXIgY2FuYXJ5ID0gMHhkZWFkYmVlZmNhZmU7XG52YXIgal9sbSA9ICgoY2FuYXJ5ICYgMHhmZmZmZmYpID09IDB4ZWZjYWZlKTtcblxuLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcblxuZnVuY3Rpb24gQmlnSW50ZWdlcihhLCBiLCBjKSB7XG4gIGlmIChhICE9IG51bGwpXG4gICAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGEpIHRoaXMuZnJvbU51bWJlcihhLCBiLCBjKTtcbiAgICBlbHNlIGlmIChiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsIDI1Nik7XG4gIGVsc2UgdGhpcy5mcm9tU3RyaW5nKGEsIGIpO1xufVxuXG4vLyByZXR1cm4gbmV3LCB1bnNldCBCaWdJbnRlZ2VyXG5cbmZ1bmN0aW9uIG5iaSgpIHtcbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpO1xufVxuXG4vLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4vLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4vLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4vLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4vLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4vLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuXG5mdW5jdGlvbiBhbTEoaSwgeCwgdywgaiwgYywgbikge1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgdiA9IHggKiB0aGlzW2krK10gKyB3W2pdICsgYztcbiAgICBjID0gTWF0aC5mbG9vcih2IC8gMHg0MDAwMDAwKTtcbiAgICB3W2orK10gPSB2ICYgMHgzZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4vLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuXG5mdW5jdGlvbiBhbTIoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHg3ZmZmLFxuICAgIHhoID0geCA+PiAxNTtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHg3ZmZmO1xuICAgIHZhciBoID0gdGhpc1tpKytdID4+IDE1O1xuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsO1xuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDdmZmYpIDw8IDE1KSArIHdbal0gKyAoYyAmIDB4M2ZmZmZmZmYpO1xuICAgIGMgPSAobCA+Pj4gMzApICsgKG0gPj4+IDE1KSArIHhoICogaCArIChjID4+PiAzMCk7XG4gICAgd1tqKytdID0gbCAmIDB4M2ZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vLyBBbHRlcm5hdGVseSwgc2V0IG1heCBkaWdpdCBiaXRzIHRvIDI4IHNpbmNlIHNvbWVcbi8vIGJyb3dzZXJzIHNsb3cgZG93biB3aGVuIGRlYWxpbmcgd2l0aCAzMi1iaXQgbnVtYmVycy5cblxuZnVuY3Rpb24gYW0zKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4M2ZmZixcbiAgICB4aCA9IHggPj4gMTQ7XG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHZhciBsID0gdGhpc1tpXSAmIDB4M2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNDtcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bDtcbiAgICBsID0geGwgKiBsICsgKChtICYgMHgzZmZmKSA8PCAxNCkgKyB3W2pdICsgYztcbiAgICBjID0gKGwgPj4gMjgpICsgKG0gPj4gMTQpICsgeGggKiBoO1xuICAgIHdbaisrXSA9IGwgJiAweGZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vKmlmKGpfbG0gJiYgKG5hdmlnYXRvciAhPSB1bmRlZmluZWQgJiYgXG5cdG5hdmlnYXRvci5hcHBOYW1lID09IFwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKSB7XG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0yO1xuICBkYml0cyA9IDMwO1xufVxuZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIG5hdmlnYXRvci5hcHBOYW1lICE9IFwiTmV0c2NhcGVcIikpIHsqL1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTE7XG5kYml0cyA9IDI2O1xuLyp9XG5lbHNlIHsgLy8gTW96aWxsYS9OZXRzY2FwZSBzZWVtcyB0byBwcmVmZXIgYW0zXG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0zO1xuICBkYml0cyA9IDI4O1xufSovXG5cbkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMSA8PCBkYml0cykgLSAxKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRWID0gKDEgPDwgZGJpdHMpO1xuXG52YXIgQklfRlAgPSA1MjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMiwgQklfRlApO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUCAtIGRiaXRzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyICogZGJpdHMgLSBCSV9GUDtcblxuLy8gRGlnaXQgY29udmVyc2lvbnNcbnZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCI7XG52YXIgQklfUkMgPSBuZXcgQXJyYXkoKTtcbnZhciByciwgdnY7XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMDsgdnYgPD0gOTsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJhXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJBXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcblxuZnVuY3Rpb24gaW50MmNoYXIobikge1xuICByZXR1cm4gQklfUk0uY2hhckF0KG4pO1xufVxuXG5mdW5jdGlvbiBpbnRBdChzLCBpKSB7XG4gIHZhciBjID0gQklfUkNbcy5jaGFyQ29kZUF0KGkpXTtcbiAgcmV0dXJuIChjID09IG51bGwpID8gLTEgOiBjO1xufVxuXG4vLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5cbmZ1bmN0aW9uIGJucEZyb21JbnQoeCkge1xuICB0aGlzLnQgPSAxO1xuICB0aGlzLnMgPSAoeCA8IDApID8gLTEgOiAwO1xuICBpZiAoeCA+IDApIHRoaXNbMF0gPSB4O1xuICBlbHNlIGlmICh4IDwgLTEpIHRoaXNbMF0gPSB4ICsgRFY7XG4gIGVsc2UgdGhpcy50ID0gMDtcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuXG5mdW5jdGlvbiBuYnYoaSkge1xuICB2YXIgciA9IG5iaSgpO1xuICByLmZyb21JbnQoaSk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5cbmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocywgYikge1xuICB2YXIgaztcbiAgaWYgKGIgPT0gMTYpIGsgPSA0O1xuICBlbHNlIGlmIChiID09IDgpIGsgPSAzO1xuICBlbHNlIGlmIChiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMTtcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDU7XG4gIGVsc2UgaWYgKGIgPT0gNCkgayA9IDI7XG4gIGVsc2Uge1xuICAgIHRoaXMuZnJvbVJhZGl4KHMsIGIpO1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnQgPSAwO1xuICB0aGlzLnMgPSAwO1xuICB2YXIgaSA9IHMubGVuZ3RoLFxuICAgIG1pID0gZmFsc2UsXG4gICAgc2ggPSAwO1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB2YXIgeCA9IChrID09IDgpID8gc1tpXSAmIDB4ZmYgOiBpbnRBdChzLCBpKTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIGlmIChzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG1pID0gZmFsc2U7XG4gICAgaWYgKHNoID09IDApXG4gICAgICB0aGlzW3RoaXMudCsrXSA9IHg7XG4gICAgZWxzZSBpZiAoc2ggKyBrID4gdGhpcy5EQikge1xuICAgICAgdGhpc1t0aGlzLnQgLSAxXSB8PSAoeCAmICgoMSA8PCAodGhpcy5EQiAtIHNoKSkgLSAxKSkgPDwgc2g7XG4gICAgICB0aGlzW3RoaXMudCsrXSA9ICh4ID4+ICh0aGlzLkRCIC0gc2gpKTtcbiAgICB9IGVsc2VcbiAgICAgIHRoaXNbdGhpcy50IC0gMV0gfD0geCA8PCBzaDtcbiAgICBzaCArPSBrO1xuICAgIGlmIChzaCA+PSB0aGlzLkRCKSBzaCAtPSB0aGlzLkRCO1xuICB9XG4gIGlmIChrID09IDggJiYgKHNbMF0gJiAweDgwKSAhPSAwKSB7XG4gICAgdGhpcy5zID0gLTE7XG4gICAgaWYgKHNoID4gMCkgdGhpc1t0aGlzLnQgLSAxXSB8PSAoKDEgPDwgKHRoaXMuREIgLSBzaCkpIC0gMSkgPDwgc2g7XG4gIH1cbiAgdGhpcy5jbGFtcCgpO1xuICBpZiAobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLCB0aGlzKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5cbmZ1bmN0aW9uIGJucENsYW1wKCkge1xuICB2YXIgYyA9IHRoaXMucyAmIHRoaXMuRE07XG4gIHdoaWxlICh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50IC0gMV0gPT0gYyktLXRoaXMudDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeFxuXG5mdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgaWYgKHRoaXMucyA8IDApIHJldHVybiBcIi1cIiArIHRoaXMubmVnYXRlKCkudG9TdHJpbmcoYik7XG4gIHZhciBrO1xuICBpZiAoYiA9PSAxNikgayA9IDQ7XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDM7XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDE7XG4gIGVsc2UgaWYgKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmIChiID09IDQpIGsgPSAyO1xuICBlbHNlIHJldHVybiB0aGlzLnRvUmFkaXgoYik7XG4gIHZhciBrbSA9ICgxIDw8IGspIC0gMSxcbiAgICBkLCBtID0gZmFsc2UsXG4gICAgciA9IFwiXCIsXG4gICAgaSA9IHRoaXMudDtcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIGs7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSA+IDApIHtcbiAgICAgIG0gPSB0cnVlO1xuICAgICAgciA9IGludDJjaGFyKGQpO1xuICAgIH1cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IGspIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8IChrIC0gcCk7XG4gICAgICAgIGQgfD0gdGhpc1stLWldID4+IChwICs9IHRoaXMuREIgLSBrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSA+PiAocCAtPSBrKSkgJiBrbTtcbiAgICAgICAgaWYgKHAgPD0gMCkge1xuICAgICAgICAgIHAgKz0gdGhpcy5EQjtcbiAgICAgICAgICAtLWk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkID4gMCkgbSA9IHRydWU7XG4gICAgICBpZiAobSkgciArPSBpbnQyY2hhcihkKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG0gPyByIDogXCIwXCI7XG59XG5cbi8vIChwdWJsaWMpIC10aGlzXG5cbmZ1bmN0aW9uIGJuTmVnYXRlKCkge1xuICB2YXIgciA9IG5iaSgpO1xuICBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB8dGhpc3xcblxuZnVuY3Rpb24gYm5BYnMoKSB7XG4gIHJldHVybiAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcztcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWxcblxuZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICB2YXIgciA9IHRoaXMucyAtIGEucztcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHZhciBpID0gdGhpcy50O1xuICByID0gaSAtIGEudDtcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHdoaWxlICgtLWkgPj0gMCkgaWYgKChyID0gdGhpc1tpXSAtIGFbaV0pICE9IDApIHJldHVybiByO1xuICByZXR1cm4gMDtcbn1cblxuLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgciA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gMTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuXG5mdW5jdGlvbiBibkJpdExlbmd0aCgpIHtcbiAgaWYgKHRoaXMudCA8PSAwKSByZXR1cm4gMDtcbiAgcmV0dXJuIHRoaXMuREIgKiAodGhpcy50IC0gMSkgKyBuYml0cyh0aGlzW3RoaXMudCAtIDFdIF4gKHRoaXMucyAmIHRoaXMuRE0pKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbipEQlxuXG5mdW5jdGlvbiBibnBETFNoaWZ0VG8obiwgcikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaSArIG5dID0gdGhpc1tpXTtcbiAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgci50ID0gdGhpcy50ICsgbjtcbiAgci5zID0gdGhpcy5zO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG5cbmZ1bmN0aW9uIGJucERSU2hpZnRUbyhuLCByKSB7XG4gIGZvciAodmFyIGkgPSBuOyBpIDwgdGhpcy50OyArK2kpIHJbaSAtIG5dID0gdGhpc1tpXTtcbiAgci50ID0gTWF0aC5tYXgodGhpcy50IC0gbiwgMCk7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgblxuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBicyA9IG4gJSB0aGlzLkRCO1xuICB2YXIgY2JzID0gdGhpcy5EQiAtIGJzO1xuICB2YXIgYm0gPSAoMSA8PCBjYnMpIC0gMTtcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQiksXG4gICAgYyA9ICh0aGlzLnMgPDwgYnMpICYgdGhpcy5ETSxcbiAgICBpO1xuICBmb3IgKGkgPSB0aGlzLnQgLSAxOyBpID49IDA7IC0taSkge1xuICAgIHJbaSArIGRzICsgMV0gPSAodGhpc1tpXSA+PiBjYnMpIHwgYztcbiAgICBjID0gKHRoaXNbaV0gJiBibSkgPDwgYnM7XG4gIH1cbiAgZm9yIChpID0gZHMgLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHJbZHNdID0gYztcbiAgci50ID0gdGhpcy50ICsgZHMgKyAxO1xuICByLnMgPSB0aGlzLnM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gblxuXG5mdW5jdGlvbiBibnBSU2hpZnRUbyhuLCByKSB7XG4gIHIucyA9IHRoaXMucztcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQik7XG4gIGlmIChkcyA+PSB0aGlzLnQpIHtcbiAgICByLnQgPSAwO1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgYnMgPSBuICUgdGhpcy5EQjtcbiAgdmFyIGNicyA9IHRoaXMuREIgLSBicztcbiAgdmFyIGJtID0gKDEgPDwgYnMpIC0gMTtcbiAgclswXSA9IHRoaXNbZHNdID4+IGJzO1xuICBmb3IgKHZhciBpID0gZHMgKyAxOyBpIDwgdGhpcy50OyArK2kpIHtcbiAgICByW2kgLSBkcyAtIDFdIHw9ICh0aGlzW2ldICYgYm0pIDw8IGNicztcbiAgICByW2kgLSBkc10gPSB0aGlzW2ldID4+IGJzO1xuICB9XG4gIGlmIChicyA+IDApIHJbdGhpcy50IC0gZHMgLSAxXSB8PSAodGhpcy5zICYgYm0pIDw8IGNicztcbiAgci50ID0gdGhpcy50IC0gZHM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5cbmZ1bmN0aW9uIGJucFN1YlRvKGEsIHIpIHtcbiAgdmFyIGkgPSAwLFxuICAgIGMgPSAwLFxuICAgIG0gPSBNYXRoLm1pbihhLnQsIHRoaXMudCk7XG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gdGhpc1tpXSAtIGFbaV07XG4gICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgYyA+Pj0gdGhpcy5EQjtcbiAgfVxuICBpZiAoYS50IDwgdGhpcy50KSB7XG4gICAgYyAtPSBhLnM7XG4gICAgd2hpbGUgKGkgPCB0aGlzLnQpIHtcbiAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyArPSB0aGlzLnM7XG4gIH0gZWxzZSB7XG4gICAgYyArPSB0aGlzLnM7XG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyAtPSBhLnM7XG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMDtcbiAgaWYgKGMgPCAtMSkgcltpKytdID0gdGhpcy5EViArIGM7XG4gIGVsc2UgaWYgKGMgPiAwKSByW2krK10gPSBjO1xuICByLnQgPSBpO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhhLCByKSB7XG4gIHZhciB4ID0gdGhpcy5hYnMoKSxcbiAgICB5ID0gYS5hYnMoKTtcbiAgdmFyIGkgPSB4LnQ7XG4gIHIudCA9IGkgKyB5LnQ7XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpICsgeC50XSA9IHguYW0oMCwgeVtpXSwgciwgaSwgMCwgeC50KTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xuICBpZiAodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcblxuZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCk7XG4gIHZhciBpID0gci50ID0gMiAqIHgudDtcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IHgudCAtIDE7ICsraSkge1xuICAgIHZhciBjID0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSk7XG4gICAgaWYgKChyW2kgKyB4LnRdICs9IHguYW0oaSArIDEsIDIgKiB4W2ldLCByLCAyICogaSArIDEsIGMsIHgudCAtIGkgLSAxKSkgPj0geC5EVikge1xuICAgICAgcltpICsgeC50XSAtPSB4LkRWO1xuICAgICAgcltpICsgeC50ICsgMV0gPSAxO1xuICAgIH1cbiAgfVxuICBpZiAoci50ID4gMCkgcltyLnQgLSAxXSArPSB4LmFtKGksIHhbaV0sIHIsIDIgKiBpLCAwLCAxKTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuXG5mdW5jdGlvbiBibnBEaXZSZW1UbyhtLCBxLCByKSB7XG4gIHZhciBwbSA9IG0uYWJzKCk7XG4gIGlmIChwbS50IDw9IDApIHJldHVybjtcbiAgdmFyIHB0ID0gdGhpcy5hYnMoKTtcbiAgaWYgKHB0LnQgPCBwbS50KSB7XG4gICAgaWYgKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApO1xuICAgIGlmIChyICE9IG51bGwpIHRoaXMuY29weVRvKHIpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAociA9PSBudWxsKSByID0gbmJpKCk7XG4gIHZhciB5ID0gbmJpKCksXG4gICAgdHMgPSB0aGlzLnMsXG4gICAgbXMgPSBtLnM7XG4gIHZhciBuc2ggPSB0aGlzLkRCIC0gbmJpdHMocG1bcG0udCAtIDFdKTsgLy8gbm9ybWFsaXplIG1vZHVsdXNcbiAgaWYgKG5zaCA+IDApIHtcbiAgICBwbS5sU2hpZnRUbyhuc2gsIHkpO1xuICAgIHB0LmxTaGlmdFRvKG5zaCwgcik7XG4gIH0gZWxzZSB7XG4gICAgcG0uY29weVRvKHkpO1xuICAgIHB0LmNvcHlUbyhyKTtcbiAgfVxuICB2YXIgeXMgPSB5LnQ7XG4gIHZhciB5MCA9IHlbeXMgLSAxXTtcbiAgaWYgKHkwID09IDApIHJldHVybjtcbiAgdmFyIHl0ID0geTAgKiAoMSA8PCB0aGlzLkYxKSArICgoeXMgPiAxKSA/IHlbeXMgLSAyXSA+PiB0aGlzLkYyIDogMCk7XG4gIHZhciBkMSA9IHRoaXMuRlYgLyB5dCxcbiAgICBkMiA9ICgxIDw8IHRoaXMuRjEpIC8geXQsXG4gICAgZSA9IDEgPDwgdGhpcy5GMjtcbiAgdmFyIGkgPSByLnQsXG4gICAgaiA9IGkgLSB5cyxcbiAgICB0ID0gKHEgPT0gbnVsbCkgPyBuYmkoKSA6IHE7XG4gIHkuZGxTaGlmdFRvKGosIHQpO1xuICBpZiAoci5jb21wYXJlVG8odCkgPj0gMCkge1xuICAgIHJbci50KytdID0gMTtcbiAgICByLnN1YlRvKHQsIHIpO1xuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cywgdCk7XG4gIHQuc3ViVG8oeSwgeSk7IC8vIFwibmVnYXRpdmVcIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyXG4gIHdoaWxlICh5LnQgPCB5cykgeVt5LnQrK10gPSAwO1xuICB3aGlsZSAoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV0gPT0geTApID8gdGhpcy5ETSA6IE1hdGguZmxvb3IocltpXSAqIGQxICsgKHJbaSAtIDFdICsgZSkgKiBkMik7XG4gICAgaWYgKChyW2ldICs9IHkuYW0oMCwgcWQsIHIsIGosIDAsIHlzKSkgPCBxZCkgeyAvLyBUcnkgaXQgb3V0XG4gICAgICB5LmRsU2hpZnRUbyhqLCB0KTtcbiAgICAgIHIuc3ViVG8odCwgcik7XG4gICAgICB3aGlsZSAocltpXSA8IC0tcWQpIHIuc3ViVG8odCwgcik7XG4gICAgfVxuICB9XG4gIGlmIChxICE9IG51bGwpIHtcbiAgICByLmRyU2hpZnRUbyh5cywgcSk7XG4gICAgaWYgKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSwgcSk7XG4gIH1cbiAgci50ID0geXM7XG4gIHIuY2xhbXAoKTtcbiAgaWYgKG5zaCA+IDApIHIuclNoaWZ0VG8obnNoLCByKTsgLy8gRGVub3JtYWxpemUgcmVtYWluZGVyXG4gIGlmICh0cyA8IDApIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuXG5mdW5jdGlvbiBibk1vZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWJzKCkuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIGlmICh0aGlzLnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSBhLnN1YlRvKHIsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG5cbmZ1bmN0aW9uIENsYXNzaWMobSkge1xuICB0aGlzLm0gPSBtO1xufVxuXG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gIGVsc2UgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGNSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7XG4gIHguZGl2UmVtVG8odGhpcy5tLCBudWxsLCB4KTtcbn1cblxuZnVuY3Rpb24gY011bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuZnVuY3Rpb24gY1NxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbkNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydDtcbkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7XG5DbGFzc2ljLnByb3RvdHlwZS5yZWR1Y2UgPSBjUmVkdWNlO1xuQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG87XG5DbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbztcblxuLy8gKHByb3RlY3RlZCkgcmV0dXJuIFwiLTEvdGhpcyAlIDJeREJcIjsgdXNlZnVsIGZvciBNb250LiByZWR1Y3Rpb25cbi8vIGp1c3RpZmljYXRpb246XG4vLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKVxuLy8gICAgICAgICB4eSA9ICAxK2ttXG4vLyAgIHh5KDIteHkpID0gKDEra20pKDEta20pXG4vLyB4W3koMi14eSldID0gMS1rXjJtXjJcbi8vIHhbeSgyLXh5KV0gPT0gMSAobW9kIG1eMilcbi8vIGlmIHkgaXMgMS94IG1vZCBtLCB0aGVuIHkoMi14eSkgaXMgMS94IG1vZCBtXjJcbi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLlxuLy8gSlMgbXVsdGlwbHkgXCJvdmVyZmxvd3NcIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLlxuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYgKHRoaXMudCA8IDEpIHJldHVybiAwO1xuICB2YXIgeCA9IHRoaXNbMF07XG4gIGlmICgoeCAmIDEpID09IDApIHJldHVybiAwO1xuICB2YXIgeSA9IHggJiAzOyAvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGYpICogeSkpICYgMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGZmKSAqIHkpKSAmIDB4ZmY7IC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5ICogKDIgLSAoKCh4ICYgMHhmZmZmKSAqIHkpICYgMHhmZmZmKSkpICYgMHhmZmZmOyAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHk7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8PSAzMiBhbmQgYXNzdW1lcyBhYmlsaXR5IHRvIGhhbmRsZSA0OC1iaXQgaW50c1xuICB5ID0gKHkgKiAoMiAtIHggKiB5ICUgdGhpcy5EVikpICUgdGhpcy5EVjsgLy8geSA9PSAxL3ggbW9kIDJeZGJpdHNcbiAgLy8gd2UgcmVhbGx5IHdhbnQgdGhlIG5lZ2F0aXZlIGludmVyc2UsIGFuZCAtRFYgPCB5IDwgRFZcbiAgcmV0dXJuICh5ID4gMCkgPyB0aGlzLkRWIC0geSA6IC15O1xufVxuXG4vLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuXG5mdW5jdGlvbiBNb250Z29tZXJ5KG0pIHtcbiAgdGhpcy5tID0gbTtcbiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTtcbiAgdGhpcy5tcGwgPSB0aGlzLm1wICYgMHg3ZmZmO1xuICB0aGlzLm1waCA9IHRoaXMubXAgPj4gMTU7XG4gIHRoaXMudW0gPSAoMSA8PCAobS5EQiAtIDE1KSkgLSAxO1xuICB0aGlzLm10MiA9IDIgKiBtLnQ7XG59XG5cbi8vIHhSIG1vZCBtXG5cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQsIHIpO1xuICByLmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgcik7XG4gIGlmICh4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ociwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyB4L1IgbW9kIG1cblxuZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHguY29weVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMilcblxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlICh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7XG4gICAgLy8gZmFzdGVyIHdheSBvZiBjYWxjdWxhdGluZyB1MCA9IHhbaV0qbXAgbW9kIERWXG4gICAgdmFyIGogPSB4W2ldICYgMHg3ZmZmO1xuICAgIHZhciB1MCA9IChqICogdGhpcy5tcGwgKyAoKChqICogdGhpcy5tcGggKyAoeFtpXSA+PiAxNSkgKiB0aGlzLm1wbCkgJiB0aGlzLnVtKSA8PCAxNSkpICYgeC5ETTtcbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSArIHRoaXMubS50O1xuICAgIHhbal0gKz0gdGhpcy5tLmFtKDAsIHUwLCB4LCBpLCAwLCB0aGlzLm0udCk7XG4gICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgd2hpbGUgKHhbal0gPj0geC5EVikge1xuICAgICAgeFtqXSAtPSB4LkRWO1xuICAgICAgeFsrK2pdKys7XG4gICAgfVxuICB9XG4gIHguY2xhbXAoKTtcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQsIHgpO1xuICBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeCk7XG59XG5cbi8vIHIgPSBcInheMi9SIG1vZCBtXCI7IHggIT0gclxuXG5mdW5jdGlvbiBtb250U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBtb250TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnQ7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0O1xuTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZTtcbk1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvO1xuTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87XG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuXG5mdW5jdGlvbiBibnBJc0V2ZW4oKSB7XG4gIHJldHVybiAoKHRoaXMudCA+IDApID8gKHRoaXNbMF0gJiAxKSA6IHRoaXMucykgPT0gMDtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuXG5mdW5jdGlvbiBibnBFeHAoZSwgeikge1xuICBpZiAoZSA+IDB4ZmZmZmZmZmYgfHwgZSA8IDEpIHJldHVybiBCaWdJbnRlZ2VyLk9ORTtcbiAgdmFyIHIgPSBuYmkoKSxcbiAgICByMiA9IG5iaSgpLFxuICAgIGcgPSB6LmNvbnZlcnQodGhpcyksXG4gICAgaSA9IG5iaXRzKGUpIC0gMTtcbiAgZy5jb3B5VG8ocik7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHouc3FyVG8ociwgcjIpO1xuICAgIGlmICgoZSAmICgxIDw8IGkpKSA+IDApIHoubXVsVG8ocjIsIGcsIHIpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocik7XG59XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcblxuZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSwgbSkge1xuICB2YXIgejtcbiAgaWYgKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTtcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIHopO1xufVxuXG4vLyBwcm90ZWN0ZWRcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbyA9IGJucENvcHlUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmc7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcCA9IGJucENsYW1wO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG8gPSBibnBMU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJUbyA9IGJucFN1YlRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2UmVtVG8gPSBibnBEaXZSZW1UbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0ID0gYm5wSW52RGlnaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5leHAgPSBibnBFeHA7XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9TdHJpbmcgPSBiblRvU3RyaW5nO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubmVnYXRlID0gYm5OZWdhdGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFicztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0TGVuZ3RoID0gYm5CaXRMZW5ndGg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvd0ludCA9IGJuTW9kUG93SW50O1xuXG4vLyBcImNvbnN0YW50c1wiXG5CaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7XG5CaWdJbnRlZ2VyLk9ORSA9IG5idigxKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyO1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4gKiBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xuICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG4gKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmVcbiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTLUlTXCIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIFxuICogRVhQUkVTUywgSU1QTElFRCBPUiBPVEhFUldJU0UsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBcbiAqIFdBUlJBTlRZIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFxuICpcbiAqIElOIE5PIEVWRU5UIFNIQUxMIFRPTSBXVSBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkNJREVOVEFMLFxuICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSXG4gKiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIE9SIE5PVCBBRFZJU0VEIE9GXG4gKiBUSEUgUE9TU0lCSUxJVFkgT0YgREFNQUdFLCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIEFSSVNJTkcgT1VUXG4gKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICpcbiAqIEluIGFkZGl0aW9uLCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBhcHBsaWVzOlxuICpcbiAqIEFsbCByZWRpc3RyaWJ1dGlvbnMgbXVzdCByZXRhaW4gYW4gaW50YWN0IGNvcHkgb2YgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhbmQgZGlzY2xhaW1lci5cbiAqL1xuXG5cbi8vIEV4dGVuZGVkIEphdmFTY3JpcHQgQk4gZnVuY3Rpb25zLCByZXF1aXJlZCBmb3IgUlNBIHByaXZhdGUgb3BzLlxuXG4vLyBWZXJzaW9uIDEuMTogbmV3IEJpZ0ludGVnZXIoXCIwXCIsIDEwKSByZXR1cm5zIFwicHJvcGVyXCIgemVyb1xuLy8gVmVyc2lvbiAxLjI6IHNxdWFyZSgpIEFQSSwgaXNQcm9iYWJsZVByaW1lIGZpeFxuXG4vLyAocHVibGljKVxuZnVuY3Rpb24gYm5DbG9uZSgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5jb3B5VG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuXG5mdW5jdGlvbiBibkludFZhbHVlKCkge1xuICBpZiAodGhpcy5zIDwgMCkge1xuICAgIGlmICh0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF0gLSB0aGlzLkRWO1xuICAgIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7XG4gIH0gZWxzZSBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdO1xuICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIDA7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gIHJldHVybiAoKHRoaXNbMV0gJiAoKDEgPDwgKDMyIC0gdGhpcy5EQikpIC0gMSkpIDw8IHRoaXMuREIpIHwgdGhpc1swXTtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcblxuZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMjQpID4+IDI0O1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuXG5mdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMTYpID4+IDE2O1xufVxuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG5cbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yICogdGhpcy5EQiAvIE1hdGgubG9nKHIpKTtcbn1cblxuLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcblxuZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gLTE7XG4gIGVsc2UgaWYgKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMDtcbiAgZWxzZSByZXR1cm4gMTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcblxuZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIjtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBhID0gTWF0aC5wb3coYiwgY3MpO1xuICB2YXIgZCA9IG5idihhKSxcbiAgICB5ID0gbmJpKCksXG4gICAgeiA9IG5iaSgpLFxuICAgIHIgPSBcIlwiO1xuICB0aGlzLmRpdlJlbVRvKGQsIHksIHopO1xuICB3aGlsZSAoeS5zaWdudW0oKSA+IDApIHtcbiAgICByID0gKGEgKyB6LmludFZhbHVlKCkpLnRvU3RyaW5nKGIpLnN1YnN0cigxKSArIHI7XG4gICAgeS5kaXZSZW1UbyhkLCB5LCB6KTtcbiAgfVxuICByZXR1cm4gei5pbnRWYWx1ZSgpLnRvU3RyaW5nKGIpICsgcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuXG5mdW5jdGlvbiBibnBGcm9tUmFkaXgocywgYikge1xuICB0aGlzLmZyb21JbnQoMCk7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBkID0gTWF0aC5wb3coYiwgY3MpLFxuICAgIG1pID0gZmFsc2UsXG4gICAgaiA9IDAsXG4gICAgdyA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkge1xuICAgIHZhciB4ID0gaW50QXQocywgaSk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgdGhpcy5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdyA9IGIgKiB3ICsgeDtcbiAgICBpZiAoKytqID49IGNzKSB7XG4gICAgICB0aGlzLmRNdWx0aXBseShkKTtcbiAgICAgIHRoaXMuZEFkZE9mZnNldCh3LCAwKTtcbiAgICAgIGogPSAwO1xuICAgICAgdyA9IDA7XG4gICAgfVxuICB9XG4gIGlmIChqID4gMCkge1xuICAgIHRoaXMuZE11bHRpcGx5KE1hdGgucG93KGIsIGopKTtcbiAgICB0aGlzLmRBZGRPZmZzZXQodywgMCk7XG4gIH1cbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgdGhpcyk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuXG5mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsIGIsIGMpIHtcbiAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGIpIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsaW50LFJORylcbiAgICBpZiAoYSA8IDIpIHRoaXMuZnJvbUludCgxKTtcbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZnJvbU51bWJlcihhLCBjKTtcbiAgICAgIGlmICghdGhpcy50ZXN0Qml0KGEgLSAxKSkgLy8gZm9yY2UgTVNCIHNldFxuICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYSAtIDEpLCBvcF9vciwgdGhpcyk7XG4gICAgICBpZiAodGhpcy5pc0V2ZW4oKSkgdGhpcy5kQWRkT2Zmc2V0KDEsIDApOyAvLyBmb3JjZSBvZGRcbiAgICAgIHdoaWxlICghdGhpcy5pc1Byb2JhYmxlUHJpbWUoYikpIHtcbiAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KDIsIDApO1xuICAgICAgICBpZiAodGhpcy5iaXRMZW5ndGgoKSA+IGEpIHRoaXMuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgdmFyIHggPSBuZXcgQXJyYXkoKSxcbiAgICAgIHQgPSBhICYgNztcbiAgICB4Lmxlbmd0aCA9IChhID4+IDMpICsgMTtcbiAgICBiLm5leHRCeXRlcyh4KTtcbiAgICBpZiAodCA+IDApIHhbMF0gJj0gKCgxIDw8IHQpIC0gMSk7XG4gICAgZWxzZSB4WzBdID0gMDtcbiAgICB0aGlzLmZyb21TdHJpbmcoeCwgMjU2KTtcbiAgfVxufVxuXG4vLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5XG5cbmZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gIHZhciBpID0gdGhpcy50LFxuICAgIHIgPSBuZXcgQXJyYXkoKTtcbiAgclswXSA9IHRoaXMucztcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIDgsXG4gICAgZCwgayA9IDA7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSAhPSAodGhpcy5zICYgdGhpcy5ETSkgPj4gcClcbiAgICAgIHJbaysrXSA9IGQgfCAodGhpcy5zIDw8ICh0aGlzLkRCIC0gcCkpO1xuICAgIHdoaWxlIChpID49IDApIHtcbiAgICAgIGlmIChwIDwgOCkge1xuICAgICAgICBkID0gKHRoaXNbaV0gJiAoKDEgPDwgcCkgLSAxKSkgPDwgKDggLSBwKTtcbiAgICAgICAgZCB8PSB0aGlzWy0taV0gPj4gKHAgKz0gdGhpcy5EQiAtIDgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldID4+IChwIC09IDgpKSAmIDB4ZmY7XG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHRoaXMuREI7XG4gICAgICAgICAgLS1pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL2lmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjtcbiAgICAgIC8vaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsraztcbiAgICAgIGlmIChrID4gMCB8fCBkICE9IHRoaXMucykgcltrKytdID0gZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA9PSAwKTtcbn1cblxuZnVuY3Rpb24gYm5NaW4oYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpIDwgMCkgPyB0aGlzIDogYTtcbn1cblxuZnVuY3Rpb24gYm5NYXgoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID4gMCkgPyB0aGlzIDogYTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcblxuZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsIG9wLCByKSB7XG4gIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSwgYVtpXSk7XG4gIGlmIChhLnQgPCB0aGlzLnQpIHtcbiAgICBmID0gYS5zICYgdGhpcy5ETTtcbiAgICBmb3IgKGkgPSBtOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLCBmKTtcbiAgICByLnQgPSB0aGlzLnQ7XG4gIH0gZWxzZSB7XG4gICAgZiA9IHRoaXMucyAmIHRoaXMuRE07XG4gICAgZm9yIChpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZiwgYVtpXSk7XG4gICAgci50ID0gYS50O1xuICB9XG4gIHIucyA9IG9wKHRoaXMucywgYS5zKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgYVxuXG5mdW5jdGlvbiBvcF9hbmQoeCwgeSkge1xuICByZXR1cm4geCAmIHk7XG59XG5cbmZ1bmN0aW9uIGJuQW5kKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCBhXG5cbmZ1bmN0aW9uIG9wX29yKHgsIHkpIHtcbiAgcmV0dXJuIHggfCB5O1xufVxuXG5mdW5jdGlvbiBibk9yKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3Bfb3IsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcblxuZnVuY3Rpb24gb3BfeG9yKHgsIHkpIHtcbiAgcmV0dXJuIHggXiB5O1xufVxuXG5mdW5jdGlvbiBiblhvcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX3hvciwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfmFcblxuZnVuY3Rpb24gb3BfYW5kbm90KHgsIHkpIHtcbiAgcmV0dXJuIHggJiB+eTtcbn1cblxuZnVuY3Rpb24gYm5BbmROb3QoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9hbmRub3QsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgfnRoaXNcblxuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNICYgfnRoaXNbaV07XG4gIHIudCA9IHRoaXMudDtcbiAgci5zID0gfnRoaXMucztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuXG5mdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGlmIChuIDwgMCkgdGhpcy5yU2hpZnRUbygtbiwgcik7XG4gIGVsc2UgdGhpcy5sU2hpZnRUbyhuLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPj4gblxuXG5mdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZiAobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4sIHIpO1xuICBlbHNlIHRoaXMuclNoaWZ0VG8obiwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG5cbmZ1bmN0aW9uIGxiaXQoeCkge1xuICBpZiAoeCA9PSAwKSByZXR1cm4gLTE7XG4gIHZhciByID0gMDtcbiAgaWYgKCh4ICYgMHhmZmZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gMTY7XG4gICAgciArPSAxNjtcbiAgfVxuICBpZiAoKHggJiAweGZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gODtcbiAgICByICs9IDg7XG4gIH1cbiAgaWYgKCh4ICYgMHhmKSA9PSAwKSB7XG4gICAgeCA+Pj0gNDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh4ICYgMykgPT0gMCkge1xuICAgIHggPj49IDI7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgoeCAmIDEpID09IDApKytyO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpXG5cbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgIGlmICh0aGlzW2ldICE9IDApIHJldHVybiBpICogdGhpcy5EQiArIGxiaXQodGhpc1tpXSk7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gdGhpcy50ICogdGhpcy5EQjtcbiAgcmV0dXJuIC0xO1xufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5cbmZ1bmN0aW9uIGNiaXQoeCkge1xuICB2YXIgciA9IDA7XG4gIHdoaWxlICh4ICE9IDApIHtcbiAgICB4ICY9IHggLSAxO1xuICAgICsrcjtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuXG5mdW5jdGlvbiBibkJpdENvdW50KCkge1xuICB2YXIgciA9IDAsXG4gICAgeCA9IHRoaXMucyAmIHRoaXMuRE07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldIF4geCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuXG5mdW5jdGlvbiBiblRlc3RCaXQobikge1xuICB2YXIgaiA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpO1xuICBpZiAoaiA+PSB0aGlzLnQpIHJldHVybiAodGhpcy5zICE9IDApO1xuICByZXR1cm4gKCh0aGlzW2pdICYgKDEgPDwgKG4gJSB0aGlzLkRCKSkpICE9IDApO1xufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzIG9wICgxPDxuKVxuXG5mdW5jdGlvbiBibnBDaGFuZ2VCaXQobiwgb3ApIHtcbiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7XG4gIHRoaXMuYml0d2lzZVRvKHIsIG9wLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcblxuZnVuY3Rpb24gYm5TZXRCaXQobikge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobiwgb3Bfb3IpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuXG5mdW5jdGlvbiBibkNsZWFyQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX2FuZG5vdCk7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcblxuZnVuY3Rpb24gYm5GbGlwQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX3hvcik7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibnBBZGRUbyhhLCByKSB7XG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHRoaXNbaV0gKyBhW2ldO1xuICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgIGMgPj49IHRoaXMuREI7XG4gIH1cbiAgaWYgKGEudCA8IHRoaXMudCkge1xuICAgIGMgKz0gYS5zO1xuICAgIHdoaWxlIChpIDwgdGhpcy50KSB7XG4gICAgICBjICs9IHRoaXNbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjICs9IGFbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gYS5zO1xuICB9XG4gIHIucyA9IChjIDwgMCkgPyAtMSA6IDA7XG4gIGlmIChjID4gMCkgcltpKytdID0gYztcbiAgZWxzZSBpZiAoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWICsgYztcbiAgci50ID0gaTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibkFkZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWRkVG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC0gYVxuXG5mdW5jdGlvbiBiblN1YnRyYWN0KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5zdWJUbyhhLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5cbmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLm11bHRpcGx5VG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzXjJcblxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuc3F1YXJlVG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC8gYVxuXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgciwgbnVsbCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuXG5mdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cblxuZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICB2YXIgcSA9IG5iaSgpLFxuICAgIHIgPSBuYmkoKTtcbiAgdGhpcy5kaXZSZW1UbyhhLCBxLCByKTtcbiAgcmV0dXJuIG5ldyBBcnJheShxLCByKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcblxuZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHtcbiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLCBuIC0gMSwgdGhpcywgMCwgMCwgdGhpcy50KTtcbiAgKyt0aGlzLnQ7XG4gIHRoaXMuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuXG5mdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sIHcpIHtcbiAgaWYgKG4gPT0gMCkgcmV0dXJuO1xuICB3aGlsZSAodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgdGhpc1t3XSArPSBuO1xuICB3aGlsZSAodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgIGlmICgrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgKyt0aGlzW3ddO1xuICB9XG59XG5cbi8vIEEgXCJudWxsXCIgcmVkdWNlclxuXG5mdW5jdGlvbiBOdWxsRXhwKCkge31cblxuZnVuY3Rpb24gbk5vcCh4KSB7XG4gIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiBuTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG59XG5cbmZ1bmN0aW9uIG5TcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG59XG5cbk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wO1xuTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcDtcbk51bGxFeHAucHJvdG90eXBlLm11bFRvID0gbk11bFRvO1xuTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZVxuXG5mdW5jdGlvbiBiblBvdyhlKSB7XG4gIHJldHVybiB0aGlzLmV4cChlLCBuZXcgTnVsbEV4cCgpKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IGxvd2VyIG4gd29yZHMgb2YgXCJ0aGlzICogYVwiLCBhLnQgPD0gblxuLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuXG5mdW5jdGlvbiBibnBNdWx0aXBseUxvd2VyVG8oYSwgbiwgcikge1xuICB2YXIgaSA9IE1hdGgubWluKHRoaXMudCArIGEudCwgbik7XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaTtcbiAgd2hpbGUgKGkgPiAwKSByWy0taV0gPSAwO1xuICB2YXIgajtcbiAgZm9yIChqID0gci50IC0gdGhpcy50OyBpIDwgajsgKytpKSByW2kgKyB0aGlzLnRdID0gdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCB0aGlzLnQpO1xuICBmb3IgKGogPSBNYXRoLm1pbihhLnQsIG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsIGFbaV0sIHIsIGksIDAsIG4gLSBpKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gXCJ0aGlzICogYVwiIHdpdGhvdXQgbG93ZXIgbiB3b3JkcywgbiA+IDBcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlVcHBlclRvKGEsIG4sIHIpIHtcbiAgLS1uO1xuICB2YXIgaSA9IHIudCA9IHRoaXMudCArIGEudCAtIG47XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gTWF0aC5tYXgobiAtIHRoaXMudCwgMCk7IGkgPCBhLnQ7ICsraSlcbiAgICByW3RoaXMudCArIGkgLSBuXSA9IHRoaXMuYW0obiAtIGksIGFbaV0sIHIsIDAsIDAsIHRoaXMudCArIGkgLSBuKTtcbiAgci5jbGFtcCgpO1xuICByLmRyU2hpZnRUbygxLCByKTtcbn1cblxuLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvblxuXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmJpKCk7XG4gIHRoaXMucTMgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIgKiBtLnQsIHRoaXMucjIpO1xuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSk7XG4gIHRoaXMubSA9IG07XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KHgpIHtcbiAgaWYgKHgucyA8IDAgfHwgeC50ID4gMiAqIHRoaXMubS50KSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgZWxzZSBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4O1xuICBlbHNlIHtcbiAgICB2YXIgciA9IG5iaSgpO1xuICAgIHguY29weVRvKHIpO1xuICAgIHRoaXMucmVkdWNlKHIpO1xuICAgIHJldHVybiByO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcblxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50IC0gMSwgdGhpcy5yMik7XG4gIGlmICh4LnQgPiB0aGlzLm0udCArIDEpIHtcbiAgICB4LnQgPSB0aGlzLm0udCArIDE7XG4gICAgeC5jbGFtcCgpO1xuICB9XG4gIHRoaXMubXUubXVsdGlwbHlVcHBlclRvKHRoaXMucjIsIHRoaXMubS50ICsgMSwgdGhpcy5xMyk7XG4gIHRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMywgdGhpcy5tLnQgKyAxLCB0aGlzLnIyKTtcbiAgd2hpbGUgKHguY29tcGFyZVRvKHRoaXMucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsIHRoaXMubS50ICsgMSk7XG4gIHguc3ViVG8odGhpcy5yMiwgeCk7XG4gIHdoaWxlICh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLCB4KTtcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5cbmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG4vLyByID0geCp5IG1vZCBtOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnQ7XG5CYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0O1xuQmFycmV0dC5wcm90b3R5cGUucmVkdWNlID0gYmFycmV0dFJlZHVjZTtcbkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvO1xuQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSlcblxuZnVuY3Rpb24gYm5Nb2RQb3coZSwgbSkge1xuICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksXG4gICAgaywgciA9IG5idigxKSxcbiAgICB6O1xuICBpZiAoaSA8PSAwKSByZXR1cm4gcjtcbiAgZWxzZSBpZiAoaSA8IDE4KSBrID0gMTtcbiAgZWxzZSBpZiAoaSA8IDQ4KSBrID0gMztcbiAgZWxzZSBpZiAoaSA8IDE0NCkgayA9IDQ7XG4gIGVsc2UgaWYgKGkgPCA3NjgpIGsgPSA1O1xuICBlbHNlIGsgPSA2O1xuICBpZiAoaSA8IDgpXG4gICAgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIGlmIChtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKTtcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKTtcblxuICAvLyBwcmVjb21wdXRhdGlvblxuICB2YXIgZyA9IG5ldyBBcnJheSgpLFxuICAgIG4gPSAzLFxuICAgIGsxID0gayAtIDEsXG4gICAga20gPSAoMSA8PCBrKSAtIDE7XG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcyk7XG4gIGlmIChrID4gMSkge1xuICAgIHZhciBnMiA9IG5iaSgpO1xuICAgIHouc3FyVG8oZ1sxXSwgZzIpO1xuICAgIHdoaWxlIChuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmJpKCk7XG4gICAgICB6Lm11bFRvKGcyLCBnW24gLSAyXSwgZ1tuXSk7XG4gICAgICBuICs9IDI7XG4gICAgfVxuICB9XG5cbiAgdmFyIGogPSBlLnQgLSAxLFxuICAgIHcsIGlzMSA9IHRydWUsXG4gICAgcjIgPSBuYmkoKSxcbiAgICB0O1xuICBpID0gbmJpdHMoZVtqXSkgLSAxO1xuICB3aGlsZSAoaiA+PSAwKSB7XG4gICAgaWYgKGkgPj0gazEpIHcgPSAoZVtqXSA+PiAoaSAtIGsxKSkgJiBrbTtcbiAgICBlbHNlIHtcbiAgICAgIHcgPSAoZVtqXSAmICgoMSA8PCAoaSArIDEpKSAtIDEpKSA8PCAoazEgLSBpKTtcbiAgICAgIGlmIChqID4gMCkgdyB8PSBlW2ogLSAxXSA+PiAodGhpcy5EQiArIGkgLSBrMSk7XG4gICAgfVxuXG4gICAgbiA9IGs7XG4gICAgd2hpbGUgKCh3ICYgMSkgPT0gMCkge1xuICAgICAgdyA+Pj0gMTtcbiAgICAgIC0tbjtcbiAgICB9XG4gICAgaWYgKChpIC09IG4pIDwgMCkge1xuICAgICAgaSArPSB0aGlzLkRCO1xuICAgICAgLS1qO1xuICAgIH1cbiAgICBpZiAoaXMxKSB7IC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgIGdbd10uY29weVRvKHIpO1xuICAgICAgaXMxID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChuID4gMSkge1xuICAgICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgICAgei5zcXJUbyhyMiwgcik7XG4gICAgICAgIG4gLT0gMjtcbiAgICAgIH1cbiAgICAgIGlmIChuID4gMCkgei5zcXJUbyhyLCByMik7XG4gICAgICBlbHNlIHtcbiAgICAgICAgdCA9IHI7XG4gICAgICAgIHIgPSByMjtcbiAgICAgICAgcjIgPSB0O1xuICAgICAgfVxuICAgICAgei5tdWxUbyhyMiwgZ1t3XSwgcik7XG4gICAgfVxuXG4gICAgd2hpbGUgKGogPj0gMCAmJiAoZVtqXSAmICgxIDw8IGkpKSA9PSAwKSB7XG4gICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgaSA9IHRoaXMuREIgLSAxO1xuICAgICAgICAtLWo7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB6LnJldmVydChyKTtcbn1cblxuLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcblxuZnVuY3Rpb24gYm5HQ0QoYSkge1xuICB2YXIgeCA9ICh0aGlzLnMgPCAwKSA/IHRoaXMubmVnYXRlKCkgOiB0aGlzLmNsb25lKCk7XG4gIHZhciB5ID0gKGEucyA8IDApID8gYS5uZWdhdGUoKSA6IGEuY2xvbmUoKTtcbiAgaWYgKHguY29tcGFyZVRvKHkpIDwgMCkge1xuICAgIHZhciB0ID0geDtcbiAgICB4ID0geTtcbiAgICB5ID0gdDtcbiAgfVxuICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksXG4gICAgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChnIDwgMCkgcmV0dXJuIHg7XG4gIGlmIChpIDwgZykgZyA9IGk7XG4gIGlmIChnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZywgeCk7XG4gICAgeS5yU2hpZnRUbyhnLCB5KTtcbiAgfVxuICB3aGlsZSAoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZiAoKGkgPSB4LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHguclNoaWZ0VG8oaSwgeCk7XG4gICAgaWYgKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGksIHkpO1xuICAgIGlmICh4LmNvbXBhcmVUbyh5KSA+PSAwKSB7XG4gICAgICB4LnN1YlRvKHksIHgpO1xuICAgICAgeC5yU2hpZnRUbygxLCB4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgeS5zdWJUbyh4LCB5KTtcbiAgICAgIHkuclNoaWZ0VG8oMSwgeSk7XG4gICAgfVxuICB9XG4gIGlmIChnID4gMCkgeS5sU2hpZnRUbyhnLCB5KTtcbiAgcmV0dXJuIHk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNlxuXG5mdW5jdGlvbiBibnBNb2RJbnQobikge1xuICBpZiAobiA8PSAwKSByZXR1cm4gMDtcbiAgdmFyIGQgPSB0aGlzLkRWICUgbixcbiAgICByID0gKHRoaXMucyA8IDApID8gbiAtIDEgOiAwO1xuICBpZiAodGhpcy50ID4gMClcbiAgICBpZiAoZCA9PSAwKSByID0gdGhpc1swXSAlIG47XG4gICAgZWxzZSBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCAqIHIgKyB0aGlzW2ldKSAlIG47XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSAxL3RoaXMgJSBtIChIQUMgMTQuNjEpXG5cbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gIGlmICgodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICB2YXIgdSA9IG0uY2xvbmUoKSxcbiAgICB2ID0gdGhpcy5jbG9uZSgpO1xuICB2YXIgYSA9IG5idigxKSxcbiAgICBiID0gbmJ2KDApLFxuICAgIGMgPSBuYnYoMCksXG4gICAgZCA9IG5idigxKTtcbiAgd2hpbGUgKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgIHdoaWxlICh1LmlzRXZlbigpKSB7XG4gICAgICB1LnJTaGlmdFRvKDEsIHUpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYS5pc0V2ZW4oKSB8fCAhYi5pc0V2ZW4oKSkge1xuICAgICAgICAgIGEuYWRkVG8odGhpcywgYSk7XG4gICAgICAgICAgYi5zdWJUbyhtLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBhLnJTaGlmdFRvKDEsIGEpO1xuICAgICAgfSBlbHNlIGlmICghYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLCBiKTtcbiAgICAgIGIuclNoaWZ0VG8oMSwgYik7XG4gICAgfVxuICAgIHdoaWxlICh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsIHYpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkge1xuICAgICAgICAgIGMuYWRkVG8odGhpcywgYyk7XG4gICAgICAgICAgZC5zdWJUbyhtLCBkKTtcbiAgICAgICAgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsIGMpO1xuICAgICAgfSBlbHNlIGlmICghZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLCBkKTtcbiAgICAgIGQuclNoaWZ0VG8oMSwgZCk7XG4gICAgfVxuICAgIGlmICh1LmNvbXBhcmVUbyh2KSA+PSAwKSB7XG4gICAgICB1LnN1YlRvKHYsIHUpO1xuICAgICAgaWYgKGFjKSBhLnN1YlRvKGMsIGEpO1xuICAgICAgYi5zdWJUbyhkLCBiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LCB2KTtcbiAgICAgIGlmIChhYykgYy5zdWJUbyhhLCBjKTtcbiAgICAgIGQuc3ViVG8oYiwgZCk7XG4gICAgfVxuICB9XG4gIGlmICh2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgaWYgKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pO1xuICBpZiAoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSwgZCk7XG4gIGVsc2UgcmV0dXJuIGQ7XG4gIGlmIChkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pO1xuICBlbHNlIHJldHVybiBkO1xufVxuXG52YXIgbG93cHJpbWVzID0gWzIsIDMsIDUsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjksIDMxLCAzNywgNDEsIDQzLCA0NywgNTMsIDU5LCA2MSwgNjcsIDcxLCA3MywgNzksIDgzLCA4OSwgOTcsIDEwMSxcbiAgICAxMDMsIDEwNywgMTA5LCAxMTMsIDEyNywgMTMxLCAxMzcsIDEzOSwgMTQ5LCAxNTEsIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNyxcbiAgICAyMjksIDIzMywgMjM5LCAyNDEsIDI1MSwgMjU3LCAyNjMsIDI2OSwgMjcxLCAyNzcsIDI4MSwgMjgzLCAyOTMsIDMwNywgMzExLCAzMTMsIDMxNywgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSxcbiAgICAzNjcsIDM3MywgMzc5LCAzODMsIDM4OSwgMzk3LCA0MDEsIDQwOSwgNDE5LCA0MjEsIDQzMSwgNDMzLCA0MzksIDQ0MywgNDQ5LCA0NTcsIDQ2MSwgNDYzLCA0NjcsIDQ3OSwgNDg3LCA0OTEsIDQ5OSxcbiAgICA1MDMsIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LCA1NzEsIDU3NywgNTg3LCA1OTMsIDU5OSwgNjAxLCA2MDcsIDYxMywgNjE3LCA2MTksIDYzMSwgNjQxLCA2NDMsIDY0NyxcbiAgICA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSwgNzA5LCA3MTksIDcyNywgNzMzLCA3MzksIDc0MywgNzUxLCA3NTcsIDc2MSwgNzY5LCA3NzMsIDc4NywgNzk3LCA4MDksIDgxMSxcbiAgICA4MjEsIDgyMywgODI3LCA4MjksIDgzOSwgODUzLCA4NTcsIDg1OSwgODYzLCA4NzcsIDg4MSwgODgzLCA4ODcsIDkwNywgOTExLCA5MTksIDkyOSwgOTM3LCA5NDEsIDk0NywgOTUzLCA5NjcsIDk3MSxcbiAgICA5NzcsIDk4MywgOTkxLCA5OTdcbl07XG52YXIgbHBsaW0gPSAoMSA8PCAyNikgLyBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdO1xuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcblxuZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkge1xuICB2YXIgaSwgeCA9IHRoaXMuYWJzKCk7XG4gIGlmICh4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZTtcbiAgaSA9IDE7XG4gIHdoaWxlIChpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgIHZhciBtID0gbG93cHJpbWVzW2ldLFxuICAgICAgaiA9IGkgKyAxO1xuICAgIHdoaWxlIChqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107XG4gICAgbSA9IHgubW9kSW50KG0pO1xuICAgIHdoaWxlIChpIDwgaikgaWYgKG0gJSBsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7XG59XG5cbi8qIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnMgKi9cblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgbiA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gMTtcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gYm5Ub01QSSgpIHtcbiAgdmFyIGJhID0gdGhpcy50b0J5dGVBcnJheSgpO1xuICB2YXIgc2l6ZSA9IChiYS5sZW5ndGggLSAxKSAqIDggKyBuYml0cyhiYVswXSk7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoc2l6ZSAmIDB4RkYwMCkgPj4gOCk7XG4gIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNpemUgJiAweEZGKTtcbiAgcmVzdWx0ICs9IHV0aWwuYmluMnN0cihiYSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKiBFTkQgb2YgYWRkaXRpb24gKi9cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChrIDw9IDApIHJldHVybiBmYWxzZTtcbiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspO1xuICB0ID0gKHQgKyAxKSA+PiAxO1xuICBpZiAodCA+IGxvd3ByaW1lcy5sZW5ndGgpIHQgPSBsb3dwcmltZXMubGVuZ3RoO1xuICB2YXIgYSA9IG5iaSgpO1xuICB2YXIgaiwgYmFzZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHtcbiAgICAvL1BpY2sgYmFzZXMgYXQgcmFuZG9tLCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGF0IDJcbiAgICBmb3IgKDs7KSB7XG4gICAgICBqID0gbG93cHJpbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxvd3ByaW1lcy5sZW5ndGgpXTtcbiAgICAgIGlmIChiYXNlcy5pbmRleE9mKGopID09IC0xKSBicmVhaztcbiAgICB9XG4gICAgYmFzZXMucHVzaChqKTtcbiAgICBhLmZyb21JbnQoaik7XG4gICAgdmFyIHkgPSBhLm1vZFBvdyhyLCB0aGlzKTtcbiAgICBpZiAoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMTtcbiAgICAgIHdoaWxlIChqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICAgIHkgPSB5Lm1vZFBvd0ludCgyLCB0aGlzKTtcbiAgICAgICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyk7XG5cbi8vIHByb3RlY3RlZFxuQmlnSW50ZWdlci5wcm90b3R5cGUuY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeCA9IGJucFRvUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZFRvID0gYm5wQWRkVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW47XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFscztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubWF4ID0gYm5NYXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnhvciA9IGJuWG9yO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQgPSBibkJpdENvdW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQgPSBibkNsZWFyQml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3QgPSBiblN1YnRyYWN0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXIgPSBiblJlbWFpbmRlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9NUEkgPSBiblRvTVBJO1xuXG4vLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxuQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlID0gYm5TcXVhcmU7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIFJTQSBpbXBsZW1lbnRhdGlvblxuXG4vKiogQG1vZHVsZSBjcnlwdG8vcHVibGljX2tleS9yc2EgKi9cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyk7XG5cbmZ1bmN0aW9uIFNlY3VyZVJhbmRvbSgpIHtcbiAgZnVuY3Rpb24gbmV4dEJ5dGVzKGJ5dGVBcnJheSkge1xuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgYnl0ZUFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICBieXRlQXJyYXlbbl0gPSByYW5kb20uZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5uZXh0Qnl0ZXMgPSBuZXh0Qnl0ZXM7XG59XG5cbmZ1bmN0aW9uIFJTQSgpIHtcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gdXNlcyBqc2JuIEJpZyBOdW0gbGlicmFyeSB0byBkZWNyeXB0IFJTQVxuICAgKiBAcGFyYW0gbVxuICAgKiAgICAgICAgICAgIG1lc3NhZ2VcbiAgICogQHBhcmFtIGRcbiAgICogICAgICAgICAgICBSU0EgZCBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBwXG4gICAqICAgICAgICAgICAgUlNBIHAgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gcVxuICAgKiAgICAgICAgICAgIFJTQSBxIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIHVcbiAgICogICAgICAgICAgICBSU0EgdSBhcyBCaWdJbnRlZ2VyXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFRoZSBkZWNyeXB0ZWQgdmFsdWUgb2YgdGhlIG1lc3NhZ2VcbiAgICovXG4gIGZ1bmN0aW9uIGRlY3J5cHQobSwgZCwgcCwgcSwgdSkge1xuICAgIHZhciB4cCA9IG0ubW9kKHApLm1vZFBvdyhkLm1vZChwLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSksIHApO1xuICAgIHZhciB4cSA9IG0ubW9kKHEpLm1vZFBvdyhkLm1vZChxLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSksIHEpO1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJyc2EuanMgZGVjcnlwdFxcbnhwbjpcIiArIHV0aWwuaGV4c3RyZHVtcCh4cC50b01QSSgpKSArIFwiXFxueHFuOlwiICsgdXRpbC5oZXhzdHJkdW1wKHhxLnRvTVBJKCkpKTtcblxuICAgIHZhciB0ID0geHEuc3VidHJhY3QoeHApO1xuICAgIGlmICh0WzBdID09IDApIHtcbiAgICAgIHQgPSB4cC5zdWJ0cmFjdCh4cSk7XG4gICAgICB0ID0gdC5tdWx0aXBseSh1KS5tb2QocSk7XG4gICAgICB0ID0gcS5zdWJ0cmFjdCh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdCA9IHQubXVsdGlwbHkodSkubW9kKHEpO1xuICAgIH1cbiAgICByZXR1cm4gdC5tdWx0aXBseShwKS5hZGQoeHApO1xuICB9XG5cbiAgLyoqXG4gICAqIGVuY3J5cHQgbWVzc2FnZVxuICAgKiBAcGFyYW0gbSBtZXNzYWdlIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIGUgcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIG4gcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcbiAgICogQHJldHVybiBCaWdJbnRlZ2VyXG4gICAqL1xuICBmdW5jdGlvbiBlbmNyeXB0KG0sIGUsIG4pIHtcbiAgICByZXR1cm4gbS5tb2RQb3dJbnQoZSwgbik7XG4gIH1cblxuICAvKiBTaWduIGFuZCBWZXJpZnkgKi9cbiAgZnVuY3Rpb24gc2lnbihtLCBkLCBuKSB7XG4gICAgcmV0dXJuIG0ubW9kUG93KGQsIG4pO1xuICB9XG5cbiAgZnVuY3Rpb24gdmVyaWZ5KHgsIGUsIG4pIHtcbiAgICByZXR1cm4geC5tb2RQb3dJbnQoZSwgbik7XG4gIH1cblxuICAvLyBcImVtcHR5XCIgUlNBIGtleSBjb25zdHJ1Y3RvclxuXG4gIGZ1bmN0aW9uIGtleU9iamVjdCgpIHtcbiAgICB0aGlzLm4gPSBudWxsO1xuICAgIHRoaXMuZSA9IDA7XG4gICAgdGhpcy5lZSA9IG51bGw7XG4gICAgdGhpcy5kID0gbnVsbDtcbiAgICB0aGlzLnAgPSBudWxsO1xuICAgIHRoaXMucSA9IG51bGw7XG4gICAgdGhpcy5kbXAxID0gbnVsbDtcbiAgICB0aGlzLmRtcTEgPSBudWxsO1xuICAgIHRoaXMudSA9IG51bGw7XG4gIH1cblxuICAvLyBHZW5lcmF0ZSBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgQiBiaXRzIGxvbmcsIHVzaW5nIHB1YmxpYyBleHB0IEVcblxuICBmdW5jdGlvbiBnZW5lcmF0ZShCLCBFKSB7XG4gICAgdmFyIGtleSA9IG5ldyBrZXlPYmplY3QoKTtcbiAgICB2YXIgcm5nID0gbmV3IFNlY3VyZVJhbmRvbSgpO1xuICAgIHZhciBxcyA9IEIgPj4gMTtcbiAgICBrZXkuZSA9IHBhcnNlSW50KEUsIDE2KTtcbiAgICBrZXkuZWUgPSBuZXcgQmlnSW50ZWdlcihFLCAxNik7XG4gICAgZm9yICg7Oykge1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICBrZXkucCA9IG5ldyBCaWdJbnRlZ2VyKEIgLSBxcywgMSwgcm5nKTtcbiAgICAgICAgaWYgKGtleS5wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDAgJiYga2V5LnAuaXNQcm9iYWJsZVByaW1lKDEwKSlcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAga2V5LnEgPSBuZXcgQmlnSW50ZWdlcihxcywgMSwgcm5nKTtcbiAgICAgICAgaWYgKGtleS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDAgJiYga2V5LnEuaXNQcm9iYWJsZVByaW1lKDEwKSlcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChrZXkucC5jb21wYXJlVG8oa2V5LnEpIDw9IDApIHtcbiAgICAgICAgdmFyIHQgPSBrZXkucDtcbiAgICAgICAga2V5LnAgPSBrZXkucTtcbiAgICAgICAga2V5LnEgPSB0O1xuICAgICAgfVxuICAgICAgdmFyIHAxID0ga2V5LnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICAgICAgdmFyIHExID0ga2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICAgICAgdmFyIHBoaSA9IHAxLm11bHRpcGx5KHExKTtcbiAgICAgIGlmIChwaGkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSB7XG4gICAgICAgIGtleS5uID0ga2V5LnAubXVsdGlwbHkoa2V5LnEpO1xuICAgICAgICBrZXkuZCA9IGtleS5lZS5tb2RJbnZlcnNlKHBoaSk7XG4gICAgICAgIGtleS5kbXAxID0ga2V5LmQubW9kKHAxKTtcbiAgICAgICAga2V5LmRtcTEgPSBrZXkuZC5tb2QocTEpO1xuICAgICAgICBrZXkudSA9IGtleS5wLm1vZEludmVyc2Uoa2V5LnEpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleTtcbiAgfVxuXG4gIHRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7XG4gIHRoaXMuZGVjcnlwdCA9IGRlY3J5cHQ7XG4gIHRoaXMudmVyaWZ5ID0gdmVyaWZ5O1xuICB0aGlzLnNpZ24gPSBzaWduO1xuICB0aGlzLmdlbmVyYXRlID0gZ2VuZXJhdGU7XG4gIHRoaXMua2V5T2JqZWN0ID0ga2V5T2JqZWN0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJTQTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxuLyoqIEBtb2R1bGUgY3J5cHRvL3JhbmRvbSAqL1xuXG52YXIgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFJldHJpZXZlIHNlY3VyZSByYW5kb20gYnl0ZSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCBsZW5ndGhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIGluIGJ5dGVzIHRvIGdlbmVyYXRlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGUgc3RyaW5nXG4gICAqL1xuICBnZXRSYW5kb21CeXRlczogZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHBzZXVkby1yYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHBzZXVkbyByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRQc2V1ZG9SYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqICh0byAtIGZyb20pKSArIGZyb207XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHNlY3VyZSByYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHNlY3VyZSByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRTZWN1cmVSYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHZhciBiaXRzID0gKCh0byAtIGZyb20pKS50b1N0cmluZygyKS5sZW5ndGg7XG4gICAgd2hpbGUgKChidWZbMF0gJiAoTWF0aC5wb3coMiwgYml0cykgLSAxKSkgPiAodG8gLSBmcm9tKSlcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7XG4gICAgcmV0dXJuIGZyb20gKyAoTWF0aC5hYnMoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0gMSkpKTtcbiAgfSxcblxuICBnZXRTZWN1cmVSYW5kb21PY3RldDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBidWZbMF0gJiAweEZGO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzZWN1cmUgcmFuZG9tIGJpZyBpbnRlZ2VyIG9mIGJpdHMgbGVuZ3RoXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0cyBCaXQgbGVuZ3RoIG9mIHRoZSBNUEkgdG8gY3JlYXRlXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFJlc3VsdGluZyBiaWcgaW50ZWdlclxuICAgKi9cbiAgZ2V0UmFuZG9tQmlnSW50ZWdlcjogZnVuY3Rpb24oYml0cykge1xuICAgIGlmIChiaXRzIDwgMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMgKyA3KSAvIDgpO1xuXG4gICAgdmFyIHJhbmRvbUJpdHMgPSB0aGlzLmdldFJhbmRvbUJ5dGVzKG51bUJ5dGVzKTtcbiAgICBpZiAoYml0cyAlIDggPiAwKSB7XG5cbiAgICAgIHJhbmRvbUJpdHMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgKE1hdGgucG93KDIsIGJpdHMgJSA4KSAtIDEpICZcbiAgICAgICAgcmFuZG9tQml0cy5jaGFyQ29kZUF0KDApKSArXG4gICAgICAgIHJhbmRvbUJpdHMuc3Vic3RyaW5nKDEpO1xuICAgIH1cbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CeXRlcyhyYW5kb21CaXRzKTtcbiAgICByZXR1cm4gbXBpLnRvQmlnSW50ZWdlcigpO1xuICB9LFxuXG4gIGdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlOiBmdW5jdGlvbihtaW4sIG1heCkge1xuICAgIGlmIChtYXguY29tcGFyZVRvKG1pbikgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByYW5nZSA9IG1heC5zdWJ0cmFjdChtaW4pO1xuICAgIHZhciByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB3aGlsZSAociA+IHJhbmdlKSB7XG4gICAgICByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1pbi5hZGQocik7XG4gIH1cblxufTtcbiIsIi8qKiBAbW9kdWxlIGNyeXB0by9zaWduYXR1cmUgKi9cblxudmFyIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleScpLFxuICBwa2NzMSA9IHJlcXVpcmUoJy4vcGtjczEuanMnKSxcbiAgaGFzaE1vZHVsZSA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gcHVibGljIEtleSBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoX2FsZ28gSGFzaCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBtc2dfTVBJcyBTaWduYXR1cmUgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNrZXlfTVBJcyBQdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIG9uIHdoZXJlIHRoZSBzaWduYXR1cmUgd2FzIGNvbXB1dGVkIG9uLlxuICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHNpZ25hdHVyZSAoc2lnX2RhdGEgd2FzIGVxdWFsIHRvIGRhdGEgb3ZlciBoYXNoKVxuICAgKi9cbiAgdmVyaWZ5OiBmdW5jdGlvbihhbGdvLCBoYXNoX2FsZ28sIG1zZ19NUElzLCBwdWJsaWNrZXlfTVBJcywgZGF0YSkge1xuICAgIHZhciBjYWxjX2hhc2ggPSBoYXNoTW9kdWxlLmRpZ2VzdChoYXNoX2FsZ28sIGRhdGEpO1xuXG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgXG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ11cbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gUlNBIFNpZ24tT25seSBbSEFDXVxuICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgdmFyIG4gPSBwdWJsaWNrZXlfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIGUgPSBwdWJsaWNrZXlfTVBJc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIHggPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIGRvcHVibGljID0gcnNhLnZlcmlmeSh4LCBlLCBuKTtcbiAgICAgICAgdmFyIGhhc2ggPSBwa2NzMS5lbXNhLmRlY29kZShoYXNoX2FsZ28sIGRvcHVibGljLnRvTVBJKCkuc3Vic3RyaW5nKDIpKTtcbiAgICAgICAgaWYgKGhhc2ggPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MxIHBhZGRpbmcgaW4gbWVzc2FnZSBvciBrZXkgaW5jb3JyZWN0LiBBYm9ydGluZy4uLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYXNoID09IGNhbGNfaGFzaDtcblxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gRWxnYW1hbCAoRW5jcnlwdC1Pbmx5KSBbRUxHQU1BTF0gW0hBQ11cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2lnbmluZyB3aXRoIEVsZ2FtYWwgaXMgbm90IGRlZmluZWQgaW4gdGhlIE9wZW5QR1Agc3RhbmRhcmQuXCIpO1xuICAgICAgY2FzZSAxNzpcbiAgICAgICAgLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXVxuICAgICAgICB2YXIgZHNhID0gbmV3IHB1YmxpY0tleS5kc2EoKTtcbiAgICAgICAgdmFyIHMxID0gbXNnX01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBzMiA9IG1zZ19NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcCA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZyA9IHB1YmxpY2tleV9NUElzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeSA9IHB1YmxpY2tleV9NUElzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IGRhdGE7XG4gICAgICAgIHZhciBkb3B1YmxpYyA9IGRzYS52ZXJpZnkoaGFzaF9hbGdvLCBzMSwgczIsIG0sIHAsIHEsIGcsIHkpO1xuICAgICAgICByZXR1cm4gZG9wdWJsaWMuY29tcGFyZVRvKHMxKSA9PSAwO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBhbGdvcml0aG0uJyk7XG4gICAgfVxuXG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNpZ25hdHVyZSBvbiBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIGhhc2ggQWxnb3JpdGhtIHRvIHVzZSAoU2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQXN5bW1ldHJpYyBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZSAoU2VlIFJGQzQ4ODAgOS4xKVxuICAgKiBAcGFyYW0ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IHB1YmxpY01QSXMgUHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAgICogb2YgdGhlIHByaXZhdGUga2V5IFxuICAgKiBAcGFyYW0ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IHNlY3JldE1QSXMgUHJpdmF0ZSBrZXkgbXVsdGlwcmVjaXNpb24gXG4gICAqIGludGVnZXJzIHdoaWNoIGlzIHVzZWQgdG8gc2lnbiB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIHNpZ25lZFxuICAgKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fVxuICAgKi9cbiAgc2lnbjogZnVuY3Rpb24oaGFzaF9hbGdvLCBhbGdvLCBrZXlJbnRlZ2VycywgZGF0YSkge1xuXG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgXG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ11cbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gUlNBIFNpZ24tT25seSBbSEFDXVxuICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgdmFyIGQgPSBrZXlJbnRlZ2Vyc1syXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIG4gPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIG0gPSBwa2NzMS5lbXNhLmVuY29kZShoYXNoX2FsZ28sXG4gICAgICAgICAgZGF0YSwga2V5SW50ZWdlcnNbMF0uYnl0ZUxlbmd0aCgpKTtcblxuICAgICAgICByZXR1cm4gcnNhLnNpZ24obSwgZCwgbikudG9NUEkoKTtcblxuICAgICAgY2FzZSAxNzpcbiAgICAgICAgLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXVxuICAgICAgICB2YXIgZHNhID0gbmV3IHB1YmxpY0tleS5kc2EoKTtcblxuICAgICAgICB2YXIgcCA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgcSA9IGtleUludGVnZXJzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZyA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeSA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeCA9IGtleUludGVnZXJzWzRdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IGRhdGE7XG4gICAgICAgIHZhciByZXN1bHQgPSBkc2Euc2lnbihoYXNoX2FsZ28sIG0sIGcsIHAsIHEsIHgpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRbMF0udG9TdHJpbmcoKSArIHJlc3VsdFsxXS50b1N0cmluZygpO1xuICAgICAgY2FzZSAxNjpcbiAgICAgICAgLy8gRWxnYW1hbCAoRW5jcnlwdC1Pbmx5KSBbRUxHQU1BTF0gW0hBQ11cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC4nKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUgYWxnb3JpdGhtLicpO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgZW5jb2RpbmcvYXJtb3IgKi9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJy4vYmFzZTY0LmpzJyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKipcbiAqIEZpbmRzIG91dCB3aGljaCBBc2NpaSBBcm1vcmluZyB0eXBlIGlzIHVzZWQuIFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFtTdHJpbmddIGFzY2lpIGFybW9yZWQgdGV4dFxuICogQHJldHVybnMge0ludGVnZXJ9IDAgPSBNRVNTQUdFIFBBUlQgbiBvZiBtXG4gKiAgICAgICAgIDEgPSBNRVNTQUdFIFBBUlQgblxuICogICAgICAgICAyID0gU0lHTkVEIE1FU1NBR0VcbiAqICAgICAgICAgMyA9IFBHUCBNRVNTQUdFXG4gKiAgICAgICAgIDQgPSBQVUJMSUMgS0VZIEJMT0NLXG4gKiAgICAgICAgIDUgPSBQUklWQVRFIEtFWSBCTE9DS1xuICogICAgICAgICBudWxsID0gdW5rbm93blxuICovXG5mdW5jdGlvbiBnZXRfdHlwZSh0ZXh0KSB7XG4gIHZhciByZUhlYWRlciA9IC9eLS0tLS0oW14tXSspLS0tLS0kXFxuL207XG5cbiAgdmFyIGhlYWRlciA9IHRleHQubWF0Y2gocmVIZWFkZXIpO1xuXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFgvWVxuICAvLyBVc2VkIGZvciBtdWx0aS1wYXJ0IG1lc3NhZ2VzLCB3aGVyZSB0aGUgYXJtb3IgaXMgc3BsaXQgYW1vbmdzdCBZXG4gIC8vIHBhcnRzLCBhbmQgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb3V0IG9mIFkuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxcZCtcXC9cXGQrLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IubXVsdGlwYXJ0X3NlY3Rpb247XG4gIH0gZWxzZVxuICAvLyBCRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBYXG4gIC8vIFVzZWQgZm9yIG11bHRpLXBhcnQgbWVzc2FnZXMsIHdoZXJlIHRoaXMgaXMgdGhlIFh0aCBwYXJ0IG9mIGFuXG4gIC8vIHVuc3BlY2lmaWVkIG51bWJlciBvZiBwYXJ0cy4gUmVxdWlyZXMgdGhlIE1FU1NBR0UtSUQgQXJtb3JcbiAgLy8gSGVhZGVyIHRvIGJlIHVzZWQuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxcZCsvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5tdWx0aXBhcnRfbGFzdDtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFNJR05BVFVSRVxuICAvLyBVc2VkIGZvciBkZXRhY2hlZCBzaWduYXR1cmVzLCBPcGVuUEdQL01JTUUgc2lnbmF0dXJlcywgYW5kXG4gIC8vIGNsZWFydGV4dCBzaWduYXR1cmVzLiBOb3RlIHRoYXQgUEdQIDIueCB1c2VzIEJFR0lOIFBHUCBNRVNTQUdFXG4gIC8vIGZvciBkZXRhY2hlZCBzaWduYXR1cmVzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5zaWduZWQ7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFXG4gIC8vIFVzZWQgZm9yIHNpZ25lZCwgZW5jcnlwdGVkLCBvciBjb21wcmVzc2VkIGZpbGVzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgTUVTU0FHRS8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLm1lc3NhZ2U7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLXG4gIC8vIFVzZWQgZm9yIGFybW9yaW5nIHB1YmxpYyBrZXlzLlxuICBpZiAoaGVhZGVyWzFdLm1hdGNoKC9CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnB1YmxpY19rZXk7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DS1xuICAvLyBVc2VkIGZvciBhcm1vcmluZyBwcml2YXRlIGtleXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnByaXZhdGVfa2V5O1xuICB9XG59XG5cbi8qKlxuICogQWRkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdG8gdGhlIGFybW9yIHZlcnNpb24gb2YgYW4gT3BlblBHUCBiaW5hcnlcbiAqIHBhY2tldCBibG9jay5cbiAqIEBhdXRob3IgIEFsZXhcbiAqIEB2ZXJzaW9uIDIwMTEtMTItMTZcbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBoZWFkZXIgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gYXJtb3JfYWRkaGVhZGVyKCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgaWYgKGNvbmZpZy5zaG93X3ZlcnNpb24pIHtcbiAgICByZXN1bHQgKz0gXCJWZXJzaW9uOiBcIiArIGNvbmZpZy52ZXJzaW9uc3RyaW5nICsgJ1xcclxcbic7XG4gIH1cbiAgaWYgKGNvbmZpZy5zaG93X2NvbW1lbnQpIHtcbiAgICByZXN1bHQgKz0gXCJDb21tZW50OiBcIiArIGNvbmZpZy5jb21tZW50c3RyaW5nICsgJ1xcclxcbic7XG4gIH1cbiAgcmVzdWx0ICs9ICdcXHJcXG4nO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIGEgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgcmV0dXJucyBpdCBiYXNlNjQgZW5jb2RlZFxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtTdHJpbmd9IEJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtXG4gKi9cbmZ1bmN0aW9uIGdldENoZWNrU3VtKGRhdGEpIHtcbiAgdmFyIGMgPSBjcmVhdGVjcmMyNChkYXRhKTtcbiAgdmFyIHN0ciA9IFwiXCIgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGMgPj4gMTYpICtcbiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDgpICYgMHhGRikgK1xuICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYyAmIDB4RkYpO1xuICByZXR1cm4gYmFzZTY0LmVuY29kZShzdHIpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGNoZWNrc3VtIG92ZXIgdGhlIGdpdmVuIGRhdGEgYW5kIGNvbXBhcmVzIGl0IHdpdGggdGhlXG4gKiBnaXZlbiBiYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcGFyYW0ge1N0cmluZ30gY2hlY2tzdW0gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqIEByZXR1cm4ge0Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIGNoZWNrc3VtIGlzIGNvcnJlY3Q7IG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiB2ZXJpZnlDaGVja1N1bShkYXRhLCBjaGVja3N1bSkge1xuICB2YXIgYyA9IGdldENoZWNrU3VtKGRhdGEpO1xuICB2YXIgZCA9IGNoZWNrc3VtO1xuICByZXR1cm4gY1swXSA9PSBkWzBdICYmIGNbMV0gPT0gZFsxXSAmJiBjWzJdID09IGRbMl07XG59XG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBhIENSQy0yNCBjaGVja3N1bSBvdmVyIGEgZ2l2ZW4gc3RyaW5nIChkYXRhKVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgQ1JDLTI0IGNoZWNrc3VtIGFzIG51bWJlclxuICovXG52YXIgY3JjX3RhYmxlID0gW1xuICAgIDB4MDAwMDAwMDAsIDB4MDA4NjRjZmIsIDB4MDE4YWQ1MGQsIDB4MDEwYzk5ZjYsIDB4MDM5M2U2ZTEsIDB4MDMxNWFhMWEsIDB4MDIxOTMzZWMsIDB4MDI5ZjdmMTcsIDB4MDdhMTgxMzksXG4gICAgMHgwNzI3Y2RjMiwgMHgwNjJiNTQzNCwgMHgwNmFkMThjZiwgMHgwNDMyNjdkOCwgMHgwNGI0MmIyMywgMHgwNWI4YjJkNSwgMHgwNTNlZmUyZSwgMHgwZmM1NGU4OSwgMHgwZjQzMDI3MixcbiAgICAweDBlNGY5Yjg0LCAweDBlYzlkNzdmLCAweDBjNTZhODY4LCAweDBjZDBlNDkzLCAweDBkZGM3ZDY1LCAweDBkNWEzMTllLCAweDA4NjRjZmIwLCAweDA4ZTI4MzRiLCAweDA5ZWUxYWJkLFxuICAgIDB4MDk2ODU2NDYsIDB4MGJmNzI5NTEsIDB4MGI3MTY1YWEsIDB4MGE3ZGZjNWMsIDB4MGFmYmIwYTcsIDB4MWYwY2QxZTksIDB4MWY4YTlkMTIsIDB4MWU4NjA0ZTQsIDB4MWUwMDQ4MWYsXG4gICAgMHgxYzlmMzcwOCwgMHgxYzE5N2JmMywgMHgxZDE1ZTIwNSwgMHgxZDkzYWVmZSwgMHgxOGFkNTBkMCwgMHgxODJiMWMyYiwgMHgxOTI3ODVkZCwgMHgxOWExYzkyNiwgMHgxYjNlYjYzMSxcbiAgICAweDFiYjhmYWNhLCAweDFhYjQ2MzNjLCAweDFhMzIyZmM3LCAweDEwYzk5ZjYwLCAweDEwNGZkMzliLCAweDExNDM0YTZkLCAweDExYzUwNjk2LCAweDEzNWE3OTgxLCAweDEzZGMzNTdhLFxuICAgIDB4MTJkMGFjOGMsIDB4MTI1NmUwNzcsIDB4MTc2ODFlNTksIDB4MTdlZTUyYTIsIDB4MTZlMmNiNTQsIDB4MTY2NDg3YWYsIDB4MTRmYmY4YjgsIDB4MTQ3ZGI0NDMsIDB4MTU3MTJkYjUsXG4gICAgMHgxNWY3NjE0ZSwgMHgzZTE5YTNkMiwgMHgzZTlmZWYyOSwgMHgzZjkzNzZkZiwgMHgzZjE1M2EyNCwgMHgzZDhhNDUzMywgMHgzZDBjMDljOCwgMHgzYzAwOTAzZSwgMHgzYzg2ZGNjNSxcbiAgICAweDM5YjgyMmViLCAweDM5M2U2ZTEwLCAweDM4MzJmN2U2LCAweDM4YjRiYjFkLCAweDNhMmJjNDBhLCAweDNhYWQ4OGYxLCAweDNiYTExMTA3LCAweDNiMjc1ZGZjLCAweDMxZGNlZDViLFxuICAgIDB4MzE1YWExYTAsXG4gICAgMHgzMDU2Mzg1NiwgMHgzMGQwNzRhZCwgMHgzMjRmMGJiYSwgMHgzMmM5NDc0MSwgMHgzM2M1ZGViNywgMHgzMzQzOTI0YywgMHgzNjdkNmM2MiwgMHgzNmZiMjA5OSwgMHgzN2Y3Yjk2ZixcbiAgICAweDM3NzFmNTk0LCAweDM1ZWU4YTgzLCAweDM1NjhjNjc4LCAweDM0NjQ1ZjhlLCAweDM0ZTIxMzc1LCAweDIxMTU3MjNiLCAweDIxOTMzZWMwLCAweDIwOWZhNzM2LCAweDIwMTllYmNkLFxuICAgIDB4MjI4Njk0ZGEsIDB4MjIwMGQ4MjEsIDB4MjMwYzQxZDcsIDB4MjM4YTBkMmMsIDB4MjZiNGYzMDIsIDB4MjYzMmJmZjksIDB4MjczZTI2MGYsIDB4MjdiODZhZjQsIDB4MjUyNzE1ZTMsXG4gICAgMHgyNWExNTkxOCwgMHgyNGFkYzBlZSwgMHgyNDJiOGMxNSwgMHgyZWQwM2NiMiwgMHgyZTU2NzA0OSwgMHgyZjVhZTliZiwgMHgyZmRjYTU0NCwgMHgyZDQzZGE1MywgMHgyZGM1OTZhOCxcbiAgICAweDJjYzkwZjVlLCAweDJjNGY0M2E1LCAweDI5NzFiZDhiLCAweDI5ZjdmMTcwLCAweDI4ZmI2ODg2LCAweDI4N2QyNDdkLCAweDJhZTI1YjZhLCAweDJhNjQxNzkxLCAweDJiNjg4ZTY3LFxuICAgIDB4MmJlZWMyOWMsIDB4N2MzMzQ3YTQsIDB4N2NiNTBiNWYsIDB4N2RiOTkyYTksIDB4N2QzZmRlNTIsIDB4N2ZhMGExNDUsIDB4N2YyNmVkYmUsIDB4N2UyYTc0NDgsIDB4N2VhYzM4YjMsXG4gICAgMHg3YjkyYzY5ZCwgMHg3YjE0OGE2NiwgMHg3YTE4MTM5MCwgMHg3YTllNWY2YiwgMHg3ODAxMjA3YywgMHg3ODg3NmM4NywgMHg3OThiZjU3MSwgMHg3OTBkYjk4YSwgMHg3M2Y2MDkyZCxcbiAgICAweDczNzA0NWQ2LCAweDcyN2NkYzIwLCAweDcyZmE5MGRiLCAweDcwNjVlZmNjLCAweDcwZTNhMzM3LCAweDcxZWYzYWMxLCAweDcxNjk3NjNhLCAweDc0NTc4ODE0LCAweDc0ZDFjNGVmLFxuICAgIDB4NzVkZDVkMTksIDB4NzU1YjExZTIsIDB4NzdjNDZlZjUsIDB4Nzc0MjIyMGUsIDB4NzY0ZWJiZjgsIDB4NzZjOGY3MDMsIDB4NjMzZjk2NGQsIDB4NjNiOWRhYjYsIDB4NjJiNTQzNDAsXG4gICAgMHg2MjMzMGZiYixcbiAgICAweDYwYWM3MGFjLCAweDYwMmEzYzU3LCAweDYxMjZhNWExLCAweDYxYTBlOTVhLCAweDY0OWUxNzc0LCAweDY0MTg1YjhmLCAweDY1MTRjMjc5LCAweDY1OTI4ZTgyLCAweDY3MGRmMTk1LFxuICAgIDB4Njc4YmJkNmUsIDB4NjY4NzI0OTgsIDB4NjYwMTY4NjMsIDB4NmNmYWQ4YzQsIDB4NmM3Yzk0M2YsIDB4NmQ3MDBkYzksIDB4NmRmNjQxMzIsIDB4NmY2OTNlMjUsIDB4NmZlZjcyZGUsXG4gICAgMHg2ZWUzZWIyOCwgMHg2ZTY1YTdkMywgMHg2YjViNTlmZCwgMHg2YmRkMTUwNiwgMHg2YWQxOGNmMCwgMHg2YTU3YzAwYiwgMHg2OGM4YmYxYywgMHg2ODRlZjNlNywgMHg2OTQyNmExMSxcbiAgICAweDY5YzQyNmVhLCAweDQyMmFlNDc2LCAweDQyYWNhODhkLCAweDQzYTAzMTdiLCAweDQzMjY3ZDgwLCAweDQxYjkwMjk3LCAweDQxM2Y0ZTZjLCAweDQwMzNkNzlhLCAweDQwYjU5YjYxLFxuICAgIDB4NDU4YjY1NGYsIDB4NDUwZDI5YjQsIDB4NDQwMWIwNDIsIDB4NDQ4N2ZjYjksIDB4NDYxODgzYWUsIDB4NDY5ZWNmNTUsIDB4NDc5MjU2YTMsIDB4NDcxNDFhNTgsIDB4NGRlZmFhZmYsXG4gICAgMHg0ZDY5ZTYwNCwgMHg0YzY1N2ZmMiwgMHg0Y2UzMzMwOSwgMHg0ZTdjNGMxZSwgMHg0ZWZhMDBlNSwgMHg0ZmY2OTkxMywgMHg0ZjcwZDVlOCwgMHg0YTRlMmJjNiwgMHg0YWM4NjczZCxcbiAgICAweDRiYzRmZWNiLCAweDRiNDJiMjMwLCAweDQ5ZGRjZDI3LCAweDQ5NWI4MWRjLCAweDQ4NTcxODJhLCAweDQ4ZDE1NGQxLCAweDVkMjYzNTlmLCAweDVkYTA3OTY0LCAweDVjYWNlMDkyLFxuICAgIDB4NWMyYWFjNjksIDB4NWViNWQzN2UsIDB4NWUzMzlmODUsIDB4NWYzZjA2NzMsIDB4NWZiOTRhODgsIDB4NWE4N2I0YTYsIDB4NWEwMWY4NWQsIDB4NWIwZDYxYWIsIDB4NWI4YjJkNTAsXG4gICAgMHg1OTE0NTI0NywgMHg1OTkyMWViYywgMHg1ODllODc0YSwgMHg1ODE4Y2JiMSwgMHg1MmUzN2IxNiwgMHg1MjY1MzdlZCwgMHg1MzY5YWUxYiwgMHg1M2VmZTJlMCwgMHg1MTcwOWRmNyxcbiAgICAweDUxZjZkMTBjLFxuICAgIDB4NTBmYTQ4ZmEsIDB4NTA3YzA0MDEsIDB4NTU0MmZhMmYsIDB4NTVjNGI2ZDQsIDB4NTRjODJmMjIsIDB4NTQ0ZTYzZDksIDB4NTZkMTFjY2UsIDB4NTY1NzUwMzUsIDB4NTc1YmM5YzMsXG4gICAgMHg1N2RkODUzOFxuXTtcblxuZnVuY3Rpb24gY3JlYXRlY3JjMjQoaW5wdXQpIHtcbiAgdmFyIGNyYyA9IDB4QjcwNENFO1xuICB2YXIgaW5kZXggPSAwO1xuXG4gIHdoaWxlICgoaW5wdXQubGVuZ3RoIC0gaW5kZXgpID4gMTYpIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDMpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDQpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDUpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDYpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDcpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDkpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEwKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxMSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEzKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxNCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTUpKSAmIDB4ZmZdO1xuICAgIGluZGV4ICs9IDE2O1xuICB9XG5cbiAgZm9yICh2YXIgaiA9IGluZGV4OyBqIDwgaW5wdXQubGVuZ3RoOyBqKyspIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpICYgMHhmZl07XG4gIH1cbiAgcmV0dXJuIGNyYyAmIDB4ZmZmZmZmO1xufVxuXG4vKipcbiAqIFNwbGl0cyBhIG1lc3NhZ2UgaW50byB0d28gcGFydHMsIHRoZSBoZWFkZXJzIGFuZCB0aGUgYm9keS4gVGhpcyBpcyBhbiBpbnRlcm5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2UgcGFydFxuICogQHJldHVybnMgeyhCb29sZWFufE9iamVjdCl9IEVpdGhlciBmYWxzZSBpbiBjYXNlIG9mIGFuIGVycm9yXG4gKiBvciBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJoZWFkZXJzXCIgY29udGFpbmluZyB0aGUgaGVhZGVycyBhbmRcbiAqIGFuZCBhbiBhdHRyaWJ1dGUgXCJib2R5XCIgY29udGFpbmluZyB0aGUgYm9keS5cbiAqL1xuZnVuY3Rpb24gc3BsaXRfaGVhZGVycyh0ZXh0KSB7XG4gIHZhciByZUVtcHR5TGluZSA9IC9eW1xcdCBdKlxcbi9tO1xuICB2YXIgaGVhZGVycyA9IFwiXCI7XG4gIHZhciBib2R5ID0gdGV4dDtcblxuICB2YXIgbWF0Y2hSZXN1bHQgPSByZUVtcHR5TGluZS5leGVjKHRleHQpO1xuXG4gIGlmIChtYXRjaFJlc3VsdCAhPSBudWxsKSB7XG4gICAgaGVhZGVycyA9IHRleHQuc2xpY2UoMCwgbWF0Y2hSZXN1bHQuaW5kZXgpO1xuICAgIGJvZHkgPSB0ZXh0LnNsaWNlKG1hdGNoUmVzdWx0LmluZGV4ICsgbWF0Y2hSZXN1bHRbMF0ubGVuZ3RoKTtcbiAgfVxuXG4gIHJldHVybiB7IGhlYWRlcnM6IGhlYWRlcnMsIGJvZHk6IGJvZHkgfTtcbn1cblxuLyoqXG4gKiBTcGxpdHMgYSBtZXNzYWdlIGludG8gdHdvIHBhcnRzLCB0aGUgYm9keSBhbmQgdGhlIGNoZWNrc3VtLiBUaGlzIGlzIGFuIGludGVybmFsIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZSBwYXJ0XG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3JcbiAqIG9yIGFuIG9iamVjdCB3aXRoIGF0dHJpYnV0ZSBcImJvZHlcIiBjb250YWluaW5nIHRoZSBib2R5XG4gKiBhbmQgYW4gYXR0cmlidXRlIFwiY2hlY2tzdW1cIiBjb250YWluaW5nIHRoZSBjaGVja3N1bS5cbiAqL1xuZnVuY3Rpb24gc3BsaXRfY2hlY2tzdW0odGV4dCkge1xuICB2YXIgcmVDaGVja3N1bVN0YXJ0ID0gL149L207XG4gIHZhciBib2R5ID0gdGV4dDtcbiAgdmFyIGNoZWNrc3VtID0gXCJcIjtcblxuICB2YXIgbWF0Y2hSZXN1bHQgPSByZUNoZWNrc3VtU3RhcnQuZXhlYyh0ZXh0KTtcblxuICBpZiAobWF0Y2hSZXN1bHQgIT0gbnVsbCkge1xuICAgIGJvZHkgPSB0ZXh0LnNsaWNlKDAsIG1hdGNoUmVzdWx0LmluZGV4KTtcbiAgICBjaGVja3N1bSA9IHRleHQuc2xpY2UobWF0Y2hSZXN1bHQuaW5kZXggKyAxKTtcbiAgfVxuXG4gIHJldHVybiB7IGJvZHk6IGJvZHksIGNoZWNrc3VtOiBjaGVja3N1bSB9O1xufVxuXG4vKipcbiAqIERlQXJtb3IgYW4gT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2U7IHZlcmlmeSB0aGUgY2hlY2tzdW0gYW5kIHJldHVyblxuICogdGhlIGVuY29kZWQgYnl0ZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJ0ZXh0XCIgY29udGFpbmluZyB0aGUgbWVzc2FnZSB0ZXh0LFxuICogYW4gYXR0cmlidXRlIFwiZGF0YVwiIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIGFuZCBcInR5cGVcIiBmb3IgdGhlIEFTQ0lJIGFybW9yIHR5cGVcbiAqL1xuZnVuY3Rpb24gZGVhcm1vcih0ZXh0KSB7XG4gIHZhciByZVNwbGl0ID0gL14tLS0tLVteLV0rLS0tLS0kXFxuL207XG5cbiAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKTtcblxuICB2YXIgdHlwZSA9IGdldF90eXBlKHRleHQpO1xuICBpZiAoIXR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vdyBBU0NJSSBhcm1vciB0eXBlJyk7XG4gIH0gXG5cbiAgdmFyIHNwbGl0dGV4dCA9IHRleHQuc3BsaXQocmVTcGxpdCk7XG5cbiAgLy8gSUUgaGFzIGEgYnVnIGluIHNwbGl0IHdpdGggYSByZS4gSWYgdGhlIHBhdHRlcm4gbWF0Y2hlcyB0aGUgYmVnaW5uaW5nIG9mIHRoZVxuICAvLyBzdHJpbmcgaXQgZG9lc24ndCBjcmVhdGUgYW4gZW1wdHkgYXJyYXkgZWxlbWVudCAwLiBTbyB3ZSBuZWVkIHRvIGRldGVjdCB0aGlzXG4gIC8vIHNvIHdlIGtub3cgdGhlIGluZGV4IG9mIHRoZSBkYXRhIHdlIGFyZSBpbnRlcmVzdGVkIGluLlxuICB2YXIgaW5kZXhCYXNlID0gMTtcblxuICB2YXIgcmVzdWx0LCBjaGVja3N1bTtcblxuICBpZiAodGV4dC5zZWFyY2gocmVTcGxpdCkgIT0gc3BsaXR0ZXh0WzBdLmxlbmd0aCkge1xuICAgIGluZGV4QmFzZSA9IDA7XG4gIH1cblxuICBpZiAodHlwZSAhPSAyKSB7XG4gICAgdmFyIG1zZyA9IHNwbGl0X2hlYWRlcnMoc3BsaXR0ZXh0W2luZGV4QmFzZV0pO1xuICAgIHZhciBtc2dfc3VtID0gc3BsaXRfY2hlY2tzdW0obXNnLmJvZHkpO1xuXG4gICAgcmVzdWx0ID0ge1xuICAgICAgZGF0YTogYmFzZTY0LmRlY29kZShtc2dfc3VtLmJvZHkpLFxuICAgICAgdHlwZTogdHlwZVxuICAgIH07XG5cbiAgICBjaGVja3N1bSA9IG1zZ19zdW0uY2hlY2tzdW07XG4gIH0gZWxzZSB7XG4gICAgLy8gUmV2ZXJzZSBkYXNoLWVzY2FwaW5nIGZvciBtc2cgYW5kIHJlbW92ZSB0cmFpbGluZyB3aGl0ZXNwYWNlIGF0IGVuZCBvZiBsaW5lXG4gICAgdmFyIG1zZyA9IHNwbGl0X2hlYWRlcnMoc3BsaXR0ZXh0W2luZGV4QmFzZV0ucmVwbGFjZSgvXi0gL21nLCAnJykucmVwbGFjZSgvW1xcdCBdK1xcbi9nLCBcIlxcblwiKSk7XG4gICAgdmFyIHNpZyA9IHNwbGl0X2hlYWRlcnMoc3BsaXR0ZXh0W2luZGV4QmFzZSArIDFdLnJlcGxhY2UoL14tIC9tZywgJycpKTtcbiAgICB2YXIgc2lnX3N1bSA9IHNwbGl0X2NoZWNrc3VtKHNpZy5ib2R5KTtcblxuICAgIHJlc3VsdCA9IHtcbiAgICAgIHRleHQ6ICBtc2cuYm9keS5yZXBsYWNlKC9cXG4kLywgJycpLnJlcGxhY2UoL1xcbi9nLCBcIlxcclxcblwiKSxcbiAgICAgIGRhdGE6IGJhc2U2NC5kZWNvZGUoc2lnX3N1bS5ib2R5KSxcbiAgICAgIHR5cGU6IHR5cGVcbiAgICB9O1xuXG4gICAgY2hlY2tzdW0gPSBzaWdfc3VtLmNoZWNrc3VtO1xuICB9XG5cbiAgaWYgKCF2ZXJpZnlDaGVja1N1bShyZXN1bHQuZGF0YSwgY2hlY2tzdW0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXNjaWkgYXJtb3IgaW50ZWdyaXR5IGNoZWNrIG9uIG1lc3NhZ2UgZmFpbGVkOiAnXCJcbiAgICAgICsgY2hlY2tzdW1cbiAgICAgICsgXCInIHNob3VsZCBiZSAnXCJcbiAgICAgICsgZ2V0Q2hlY2tTdW0ocmVzdWx0KSArIFwiJ1wiKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cblxuLyoqXG4gKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2tcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxuICogQHBhcmFtIGJvZHlcbiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbFxuICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0XG4gKi9cbmZ1bmN0aW9uIGFybW9yKG1lc3NhZ2V0eXBlLCBib2R5LCBwYXJ0aW5kZXgsIHBhcnR0b3RhbCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgc3dpdGNoIChtZXNzYWdldHlwZSkge1xuICAgIGNhc2UgZW51bXMuYXJtb3IubXVsdGlwYXJ0X3NlY3Rpb246XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLm11dGxpcGFydF9sYXN0OlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBcIiArIHBhcnRpbmRleCArIFwiLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnNpZ25lZDpcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05FRCBNRVNTQUdFLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIkhhc2g6IFwiICsgYm9keS5oYXNoICsgXCJcXHJcXG5cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBib2R5LnRleHQucmVwbGFjZSgvXFxuLS9nLCBcIlxcbi0gLVwiKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5LmRhdGEpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keS5kYXRhKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZW51bXMuYXJtb3IubWVzc2FnZTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoYm9keSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShib2R5KSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnB1YmxpY19rZXk6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcclxcblxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5wcml2YXRlX2tleTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVuY29kZTogYXJtb3IsXG4gIGRlY29kZTogZGVhcm1vclxufTtcbiIsIi8qIE9wZW5QR1AgcmFkaXgtNjQvYmFzZTY0IHN0cmluZyBlbmNvZGluZy9kZWNvZGluZ1xuICogQ29weXJpZ2h0IDIwMDUgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAxLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIFxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3JcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XG4gKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgXG4gKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0XG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHNcbiAqIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi5cbiAqL1xuXG4vKiogQG1vZHVsZSBlbmNvZGluZy9iYXNlNjQgKi9cblxudmFyIGI2NHMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cbmZ1bmN0aW9uIHMycih0KSB7XG4gIHZhciBhLCBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIGwgPSAwLFxuICAgIHMgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSB0LmNoYXJDb2RlQXQobik7XG4gICAgaWYgKHMgPT0gMCkge1xuICAgICAgciArPSBiNjRzLmNoYXJBdCgoYyA+PiAyKSAmIDYzKTtcbiAgICAgIGEgPSAoYyAmIDMpIDw8IDQ7XG4gICAgfSBlbHNlIGlmIChzID09IDEpIHtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoKGEgfCAoYyA+PiA0KSAmIDE1KSk7XG4gICAgICBhID0gKGMgJiAxNSkgPDwgMjtcbiAgICB9IGVsc2UgaWYgKHMgPT0gMikge1xuICAgICAgciArPSBiNjRzLmNoYXJBdChhIHwgKChjID4+IDYpICYgMykpO1xuICAgICAgbCArPSAxO1xuICAgICAgaWYgKChsICUgNjApID09IDApXG4gICAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoYyAmIDYzKTtcbiAgICB9XG4gICAgbCArPSAxO1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuXG4gICAgcyArPSAxO1xuICAgIGlmIChzID09IDMpXG4gICAgICBzID0gMDtcbiAgfVxuICBpZiAocyA+IDApIHtcbiAgICByICs9IGI2NHMuY2hhckF0KGEpO1xuICAgIGwgKz0gMTtcbiAgICBpZiAoKGwgJSA2MCkgPT0gMClcbiAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICByICs9ICc9JztcbiAgICBsICs9IDE7XG4gIH1cbiAgaWYgKHMgPT0gMSkge1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuICAgIHIgKz0gJz0nO1xuICB9XG5cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHIycyh0KSB7XG4gIHZhciBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIHMgPSAwLFxuICAgIGEgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSBiNjRzLmluZGV4T2YodC5jaGFyQXQobikpO1xuICAgIGlmIChjID49IDApIHtcbiAgICAgIGlmIChzKVxuICAgICAgICByICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYSB8IChjID4+ICg2IC0gcykpICYgMjU1KTtcbiAgICAgIHMgPSAocyArIDIpICYgNztcbiAgICAgIGEgPSAoYyA8PCBzKSAmIDI1NTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmNvZGU6IHMycixcbiAgZGVjb2RlOiByMnNcbn1cbiIsIi8qKiBAbW9kdWxlIGVudW1zICovXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKiBBIHN0cmluZyB0byBrZXkgc3BlY2lmaWVyIHR5cGVcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqL1xuICBzMms6IHtcbiAgICBzaW1wbGU6IDAsXG4gICAgc2FsdGVkOiAxLFxuICAgIGl0ZXJhdGVkOiAzLFxuICAgIGdudTogMTAxXG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4xXG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKi9cbiAgcHVibGljS2V5OiB7XG4gICAgcnNhX2VuY3J5cHRfc2lnbjogMSxcbiAgICByc2FfZW5jcnlwdDogMixcbiAgICByc2Ffc2lnbjogMyxcbiAgICBlbGdhbWFsOiAxNixcbiAgICBkc2E6IDE3XG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4yXG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKi9cbiAgc3ltbWV0cmljOiB7XG4gICAgcGxhaW50ZXh0OiAwLFxuICAgIC8qKiBOb3QgaW1wbGVtZW50ZWQhICovXG4gICAgaWRlYTogMSxcbiAgICB0cmlwbGVkZXM6IDIsXG4gICAgY2FzdDU6IDMsXG4gICAgYmxvd2Zpc2g6IDQsXG4gICAgYWVzMTI4OiA3LFxuICAgIGFlczE5MjogOCxcbiAgICBhZXMyNTY6IDksXG4gICAgdHdvZmlzaDogMTBcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjNcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqL1xuICBjb21wcmVzc2lvbjoge1xuICAgIHVuY29tcHJlc3NlZDogMCxcbiAgICAvKiogUkZDMTk1MSAqL1xuICAgIHppcDogMSxcbiAgICAvKiogUkZDMTk1MCAqL1xuICAgIHpsaWI6IDIsXG4gICAgYnppcDI6IDNcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjRcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqL1xuICBoYXNoOiB7XG4gICAgbWQ1OiAxLFxuICAgIHNoYTE6IDIsXG4gICAgcmlwZW1kOiAzLFxuICAgIHNoYTI1NjogOCxcbiAgICBzaGEzODQ6IDksXG4gICAgc2hhNTEyOiAxMCxcbiAgICBzaGEyMjQ6IDExXG4gIH0sXG5cblxuICAvKiogQSBsaXN0IG9mIHBhY2tldCB0eXBlcyBhbmQgbnVtZXJpYyB0YWdzIGFzc29jaWF0ZWQgd2l0aCB0aGVtLlxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIHBhY2tldDoge1xuICAgIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiAxLFxuICAgIHNpZ25hdHVyZTogMixcbiAgICBzeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiAzLFxuICAgIG9uZV9wYXNzX3NpZ25hdHVyZTogNCxcbiAgICBzZWNyZXRfa2V5OiA1LFxuICAgIHB1YmxpY19rZXk6IDYsXG4gICAgc2VjcmV0X3N1YmtleTogNyxcbiAgICBjb21wcmVzc2VkOiA4LFxuICAgIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiA5LFxuICAgIG1hcmtlcjogMTAsXG4gICAgbGl0ZXJhbDogMTEsXG4gICAgdHJ1c3Q6IDEyLFxuICAgIHVzZXJpZDogMTMsXG4gICAgcHVibGljX3N1YmtleTogMTQsXG4gICAgdXNlcl9hdHRyaWJ1dGU6IDE3LFxuICAgIHN5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZDogMTgsXG4gICAgbW9kaWZpY2F0aW9uX2RldGVjdGlvbl9jb2RlOiAxOVxuICB9LFxuXG5cbiAgLyoqIERhdGEgdHlwZXMgaW4gdGhlIGxpdGVyYWwgcGFja2V0XG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKi9cbiAgbGl0ZXJhbDoge1xuICAgIC8qKiBCaW5hcnkgZGF0YSAnYicgKi9cbiAgICBiaW5hcnk6ICdiJy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFRleHQgZGF0YSAndCcgKi9cbiAgICB0ZXh0OiAndCcuY2hhckNvZGVBdCgpLFxuICAgIC8qKiBVdGY4IGRhdGEgJ3UnICovXG4gICAgdXRmODogJ3UnLmNoYXJDb2RlQXQoKVxuICB9LFxuXG5cbiAgLyoqIE9uZSBwYXNzIHNpZ25hdHVyZSBwYWNrZXQgdHlwZVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIHNpZ25hdHVyZToge1xuICAgIC8qKiAweDAwOiBTaWduYXR1cmUgb2YgYSBiaW5hcnkgZG9jdW1lbnQuICovXG4gICAgYmluYXJ5OiAwLFxuICAgIC8qKiAweDAxOiBTaWduYXR1cmUgb2YgYSBjYW5vbmljYWwgdGV4dCBkb2N1bWVudC5cbiAgICAgKiBDYW5vbmljYWx5emluZyB0aGUgZG9jdW1lbnQgYnkgY29udmVydGluZyBsaW5lIGVuZGluZ3MuICovXG4gICAgdGV4dDogMSxcbiAgICAvKiogMHgwMjogU3RhbmRhbG9uZSBzaWduYXR1cmUuXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgYSBzaWduYXR1cmUgb2Ygb25seSBpdHMgb3duIHN1YnBhY2tldCBjb250ZW50cy5cbiAgICAgKiBJdCBpcyBjYWxjdWxhdGVkIGlkZW50aWNhbGx5IHRvIGEgc2lnbmF0dXJlIG92ZXIgYSB6ZXJvLWxlbmdoXG4gICAgICogYmluYXJ5IGRvY3VtZW50LiAgTm90ZSB0aGF0IGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byBoYXZlIGEgVjNcbiAgICAgKiBzdGFuZGFsb25lIHNpZ25hdHVyZS4gKi9cbiAgICBzdGFuZGFsb25lOiAyLFxuICAgIC8qKiAweDEwOiBHZW5lcmljIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBkb2VzIG5vdCBtYWtlIGFueSBwYXJ0aWN1bGFyXG4gICAgICogYXNzZXJ0aW9uIGFzIHRvIGhvdyB3ZWxsIHRoZSBjZXJ0aWZpZXIgaGFzIGNoZWNrZWQgdGhhdCB0aGUgb3duZXJcbiAgICAgKiBvZiB0aGUga2V5IGlzIGluIGZhY3QgdGhlIHBlcnNvbiBkZXNjcmliZWQgYnkgdGhlIFVzZXIgSUQuICovXG4gICAgY2VydF9nZW5lcmljOiAxNixcbiAgICAvKiogMHgxMTogUGVyc29uYSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIG5vdCBkb25lIGFueSB2ZXJpZmljYXRpb24gb2ZcbiAgICAgKiB0aGUgY2xhaW0gdGhhdCB0aGUgb3duZXIgb2YgdGhpcyBrZXkgaXMgdGhlIFVzZXIgSUQgc3BlY2lmaWVkLiAqL1xuICAgIGNlcnRfcGVyc29uYTogMTcsXG4gICAgLyoqIDB4MTI6IENhc3VhbCBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIGRvbmUgc29tZSBjYXN1YWxcbiAgICAgKiB2ZXJpZmljYXRpb24gb2YgdGhlIGNsYWltIG9mIGlkZW50aXR5LiAqL1xuICAgIGNlcnRfY2FzdWFsOiAxOCxcbiAgICAvKiogMHgxMzogUG9zaXRpdmUgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuICAgICAqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBkb25lIHN1YnN0YW50aWFsXG4gICAgICogdmVyaWZpY2F0aW9uIG9mIHRoZSBjbGFpbSBvZiBpZGVudGl0eS5cbiAgICAgKiBcbiAgICAgKiBNb3N0IE9wZW5QR1AgaW1wbGVtZW50YXRpb25zIG1ha2UgdGhlaXIgXCJrZXkgc2lnbmF0dXJlc1wiIGFzIDB4MTBcbiAgICAgKiBjZXJ0aWZpY2F0aW9ucy4gIFNvbWUgaW1wbGVtZW50YXRpb25zIGNhbiBpc3N1ZSAweDExLTB4MTNcbiAgICAgKiBjZXJ0aWZpY2F0aW9ucywgYnV0IGZldyBkaWZmZXJlbnRpYXRlIGJldHdlZW4gdGhlIHR5cGVzLiAqL1xuICAgIGNlcnRfcG9zaXRpdmU6IDE5LFxuICAgIC8qKiAweDMwOiBDZXJ0aWZpY2F0aW9uIHJldm9jYXRpb24gc2lnbmF0dXJlXG4gICAgICogVGhpcyBzaWduYXR1cmUgcmV2b2tlcyBhbiBlYXJsaWVyIFVzZXIgSUQgY2VydGlmaWNhdGlvbiBzaWduYXR1cmVcbiAgICAgKiAoc2lnbmF0dXJlIGNsYXNzIDB4MTAgdGhyb3VnaCAweDEzKSBvciBkaXJlY3Qta2V5IHNpZ25hdHVyZVxuICAgICAqICgweDFGKS4gIEl0IHNob3VsZCBiZSBpc3N1ZWQgYnkgdGhlIHNhbWUga2V5IHRoYXQgaXNzdWVkIHRoZVxuICAgICAqIHJldm9rZWQgc2lnbmF0dXJlIG9yIGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXkuICBUaGUgc2lnbmF0dXJlXG4gICAgICogaXMgY29tcHV0ZWQgb3ZlciB0aGUgc2FtZSBkYXRhIGFzIHRoZSBjZXJ0aWZpY2F0ZSB0aGF0IGl0XG4gICAgICogcmV2b2tlcywgYW5kIHNob3VsZCBoYXZlIGEgbGF0ZXIgY3JlYXRpb24gZGF0ZSB0aGFuIHRoYXRcbiAgICAgKiBjZXJ0aWZpY2F0ZS4gKi9cbiAgICBjZXJ0X3Jldm9jYXRpb246IDQ4LFxuICAgIC8qKiAweDE4OiBTdWJrZXkgQmluZGluZyBTaWduYXR1cmVcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSB0aGUgdG9wLWxldmVsIHNpZ25pbmcga2V5IHRoYXRcbiAgICAgKiBpbmRpY2F0ZXMgdGhhdCBpdCBvd25zIHRoZSBzdWJrZXkuICBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkXG4gICAgICogZGlyZWN0bHkgb24gdGhlIHByaW1hcnkga2V5IGFuZCBzdWJrZXksIGFuZCBub3Qgb24gYW55IFVzZXIgSUQgb3JcbiAgICAgKiBvdGhlciBwYWNrZXRzLiAgQSBzaWduYXR1cmUgdGhhdCBiaW5kcyBhIHNpZ25pbmcgc3Via2V5IE1VU1QgaGF2ZVxuICAgICAqIGFuIEVtYmVkZGVkIFNpZ25hdHVyZSBzdWJwYWNrZXQgaW4gdGhpcyBiaW5kaW5nIHNpZ25hdHVyZSB0aGF0XG4gICAgICogY29udGFpbnMgYSAweDE5IHNpZ25hdHVyZSBtYWRlIGJ5IHRoZSBzaWduaW5nIHN1YmtleSBvbiB0aGVcbiAgICAgKiBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAqL1xuICAgIHN1YmtleV9iaW5kaW5nOiAyNCxcbiAgICAvKiogMHgxOTogUHJpbWFyeSBLZXkgQmluZGluZyBTaWduYXR1cmVcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSBhIHNpZ25pbmcgc3Via2V5LCBpbmRpY2F0aW5nXG4gICAgICogdGhhdCBpdCBpcyBvd25lZCBieSB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4gIFRoaXMgc2lnbmF0dXJlXG4gICAgICogaXMgY2FsY3VsYXRlZCB0aGUgc2FtZSB3YXkgYXMgYSAweDE4IHNpZ25hdHVyZTogZGlyZWN0bHkgb24gdGhlXG4gICAgICogcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvciBvdGhlciBwYWNrZXRzLlxuXG4gICAgICogV2hlbiBhIHNpZ25hdHVyZSBpcyBtYWRlIG92ZXIgYSBrZXksIHRoZSBoYXNoIGRhdGEgc3RhcnRzIHdpdGggdGhlXG4gICAgICogb2N0ZXQgMHg5OSwgZm9sbG93ZWQgYnkgYSB0d28tb2N0ZXQgbGVuZ3RoIG9mIHRoZSBrZXksIGFuZCB0aGVuIGJvZHlcbiAgICAgKiBvZiB0aGUga2V5IHBhY2tldC4gIChOb3RlIHRoYXQgdGhpcyBpcyBhbiBvbGQtc3R5bGUgcGFja2V0IGhlYWRlciBmb3JcbiAgICAgKiBhIGtleSBwYWNrZXQgd2l0aCB0d28tb2N0ZXQgbGVuZ3RoLikgIEEgc3Via2V5IGJpbmRpbmcgc2lnbmF0dXJlXG4gICAgICogKHR5cGUgMHgxOCkgb3IgcHJpbWFyeSBrZXkgYmluZGluZyBzaWduYXR1cmUgKHR5cGUgMHgxOSkgdGhlbiBoYXNoZXNcbiAgICAgKiB0aGUgc3Via2V5IHVzaW5nIHRoZSBzYW1lIGZvcm1hdCBhcyB0aGUgbWFpbiBrZXkgKGFsc28gdXNpbmcgMHg5OSBhc1xuICAgICAqIHRoZSBmaXJzdCBvY3RldCkuICovXG4gICAga2V5X2JpbmRpbmc6IDI1LFxuICAgIC8qKiAweDFGOiBTaWduYXR1cmUgZGlyZWN0bHkgb24gYSBrZXlcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIGEga2V5LiAgSXQgYmluZHMgdGhlXG4gICAgICogaW5mb3JtYXRpb24gaW4gdGhlIFNpZ25hdHVyZSBzdWJwYWNrZXRzIHRvIHRoZSBrZXksIGFuZCBpc1xuICAgICAqIGFwcHJvcHJpYXRlIHRvIGJlIHVzZWQgZm9yIHN1YnBhY2tldHMgdGhhdCBwcm92aWRlIGluZm9ybWF0aW9uXG4gICAgICogYWJvdXQgdGhlIGtleSwgc3VjaCBhcyB0aGUgUmV2b2NhdGlvbiBLZXkgc3VicGFja2V0LiAgSXQgaXMgYWxzb1xuICAgICAqIGFwcHJvcHJpYXRlIGZvciBzdGF0ZW1lbnRzIHRoYXQgbm9uLXNlbGYgY2VydGlmaWVycyB3YW50IHRvIG1ha2VcbiAgICAgKiBhYm91dCB0aGUga2V5IGl0c2VsZiwgcmF0aGVyIHRoYW4gdGhlIGJpbmRpbmcgYmV0d2VlbiBhIGtleSBhbmQgYVxuICAgICAqIG5hbWUuICovXG4gICAga2V5OiAzMSxcbiAgICAvKiogMHgyMDogS2V5IHJldm9jYXRpb24gc2lnbmF0dXJlXG4gICAgICogVGhlIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4gIEFcbiAgICAgKiByZXZva2VkIGtleSBpcyBub3QgdG8gYmUgdXNlZC4gIE9ubHkgcmV2b2NhdGlvbiBzaWduYXR1cmVzIGJ5IHRoZVxuICAgICAqIGtleSBiZWluZyByZXZva2VkLCBvciBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmVcbiAgICAgKiBjb25zaWRlcmVkIHZhbGlkIHJldm9jYXRpb24gc2lnbmF0dXJlcy5hICovXG4gICAga2V5X3Jldm9jYXRpb246IDMyLFxuICAgIC8qKiAweDI4OiBTdWJrZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVcbiAgICAgKiBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIHN1YmtleSBiZWluZyByZXZva2VkLlxuICAgICAqIEEgcmV2b2tlZCBzdWJrZXkgaXMgbm90IHRvIGJlIHVzZWQuICBPbmx5IHJldm9jYXRpb24gc2lnbmF0dXJlc1xuICAgICAqIGJ5IHRoZSB0b3AtbGV2ZWwgc2lnbmF0dXJlIGtleSB0aGF0IGlzIGJvdW5kIHRvIHRoaXMgc3Via2V5LCBvclxuICAgICAqIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZSBjb25zaWRlcmVkIHZhbGlkXG4gICAgICogcmV2b2NhdGlvbiBzaWduYXR1cmVzLlxuICAgICAqIEtleSByZXZvY2F0aW9uIHNpZ25hdHVyZXMgKHR5cGVzIDB4MjAgYW5kIDB4MjgpXG4gICAgICogaGFzaCBvbmx5IHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4gKi9cbiAgICBzdWJrZXlfcmV2b2NhdGlvbjogNDAsXG4gICAgLyoqIDB4NDA6IFRpbWVzdGFtcCBzaWduYXR1cmUuXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgb25seSBtZWFuaW5nZnVsIGZvciB0aGUgdGltZXN0YW1wIGNvbnRhaW5lZCBpblxuICAgICAqIGl0LiAqL1xuICAgIHRpbWVzdGFtcDogNjQsXG4gICAgLyoqICAgIDB4NTA6IFRoaXJkLVBhcnR5IENvbmZpcm1hdGlvbiBzaWduYXR1cmUuXG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgYSBzaWduYXR1cmUgb3ZlciBzb21lIG90aGVyIE9wZW5QR1AgU2lnbmF0dXJlXG4gICAgICogcGFja2V0KHMpLiAgSXQgaXMgYW5hbG9nb3VzIHRvIGEgbm90YXJ5IHNlYWwgb24gdGhlIHNpZ25lZCBkYXRhLlxuICAgICAqIEEgdGhpcmQtcGFydHkgc2lnbmF0dXJlIFNIT1VMRCBpbmNsdWRlIFNpZ25hdHVyZSBUYXJnZXRcbiAgICAgKiBzdWJwYWNrZXQocykgdG8gZ2l2ZSBlYXN5IGlkZW50aWZpY2F0aW9uLiAgTm90ZSB0aGF0IHdlIHJlYWxseSBkb1xuICAgICAqIG1lYW4gU0hPVUxELiAgVGhlcmUgYXJlIHBsYXVzaWJsZSB1c2VzIGZvciB0aGlzIChzdWNoIGFzIGEgYmxpbmRcbiAgICAgKiBwYXJ0eSB0aGF0IG9ubHkgc2VlcyB0aGUgc2lnbmF0dXJlLCBub3QgdGhlIGtleSBvciBzb3VyY2VcbiAgICAgKiBkb2N1bWVudCkgdGhhdCBjYW5ub3QgaW5jbHVkZSBhIHRhcmdldCBzdWJwYWNrZXQuICovXG4gICAgdGhpcmRfcGFydHk6IDgwXG4gIH0sXG5cbiAgLyoqIFNpZ25hdHVyZSBzdWJwYWNrZXQgdHlwZVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIHNpZ25hdHVyZVN1YnBhY2tldDoge1xuICAgIHNpZ25hdHVyZV9jcmVhdGlvbl90aW1lOiAyLFxuICAgIHNpZ25hdHVyZV9leHBpcmF0aW9uX3RpbWU6IDMsXG4gICAgZXhwb3J0YWJsZV9jZXJ0aWZpY2F0aW9uOiA0LFxuICAgIHRydXN0X3NpZ25hdHVyZTogNSxcbiAgICByZWd1bGFyX2V4cHJlc3Npb246IDYsXG4gICAgcmV2b2NhYmxlOiA3LFxuICAgIGtleV9leHBpcmF0aW9uX3RpbWU6IDksXG4gICAgcGxhY2Vob2xkZXJfYmFja3dhcmRzX2NvbXBhdGliaWxpdHk6IDEwLFxuICAgIHByZWZlcnJlZF9zeW1tZXRyaWNfYWxnb3JpdGhtczogMTEsXG4gICAgcmV2b2NhdGlvbl9rZXk6IDEyLFxuICAgIGlzc3VlcjogMTYsXG4gICAgbm90YXRpb25fZGF0YTogMjAsXG4gICAgcHJlZmVycmVkX2hhc2hfYWxnb3JpdGhtczogMjEsXG4gICAgcHJlZmVycmVkX2NvbXByZXNzaW9uX2FsZ29yaXRobXM6IDIyLFxuICAgIGtleV9zZXJ2ZXJfcHJlZmVyZW5jZXM6IDIzLFxuICAgIHByZWZlcnJlZF9rZXlfc2VydmVyOiAyNCxcbiAgICBwcmltYXJ5X3VzZXJfaWQ6IDI1LFxuICAgIHBvbGljeV91cmk6IDI2LFxuICAgIGtleV9mbGFnczogMjcsXG4gICAgc2lnbmVyc191c2VyX2lkOiAyOCxcbiAgICByZWFzb25fZm9yX3Jldm9jYXRpb246IDI5LFxuICAgIGZlYXR1cmVzOiAzMCxcbiAgICBzaWduYXR1cmVfdGFyZ2V0OiAzMSxcbiAgICBlbWJlZGRlZF9zaWduYXR1cmU6IDMyXG4gIH0sXG5cbiAgLyoqIEtleSBmbGFnc1xuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIGtleUZsYWdzOiB7XG4gICAgLy8gMHgwMSAtIFRoaXMga2V5IG1heSBiZSB1c2VkIHRvIGNlcnRpZnkgb3RoZXIga2V5cy5cbiAgICBjZXJ0aWZ5X2tleXM6IDEsXG4gICAgLy8gMHgwMiAtIFRoaXMga2V5IG1heSBiZSB1c2VkIHRvIHNpZ24gZGF0YS5cbiAgICBzaWduX2RhdGE6IDIsXG4gICAgLy8gMHgwNCAtIFRoaXMga2V5IG1heSBiZSB1c2VkIHRvIGVuY3J5cHQgY29tbXVuaWNhdGlvbnMuXG4gICAgZW5jcnlwdF9jb21tdW5pY2F0aW9uOiA0LFxuICAgIC8vIDB4MDggLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBlbmNyeXB0IHN0b3JhZ2UuXG4gICAgZW5jcnlwdF9zdG9yYWdlOiA4LFxuICAgIC8vIDB4MTAgLSBUaGUgcHJpdmF0ZSBjb21wb25lbnQgb2YgdGhpcyBrZXkgbWF5IGhhdmUgYmVlbiBzcGxpdFxuICAgIC8vICAgICAgICBieSBhIHNlY3JldC1zaGFyaW5nIG1lY2hhbmlzbS5cbiAgICBzcGxpdF9wcml2YXRlX2tleTogMTYsXG4gICAgLy8gMHgyMCAtIFRoaXMga2V5IG1heSBiZSB1c2VkIGZvciBhdXRoZW50aWNhdGlvbi5cbiAgICBhdXRoZW50aWNhdGlvbjogMzIsXG4gICAgLy8gMHg4MCAtIFRoZSBwcml2YXRlIGNvbXBvbmVudCBvZiB0aGlzIGtleSBtYXkgYmUgaW4gdGhlXG4gICAgLy8gICAgICAgIHBvc3Nlc3Npb24gb2YgbW9yZSB0aGFuIG9uZSBwZXJzb24uXG4gICAgc2hhcmVkX3ByaXZhdGVfa2V5OiAxMjhcbiAgfSxcblxuICAvKiogS2V5IHN0YXR1c1xuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIGtleVN0YXR1czoge1xuICAgIGludmFsaWQ6ICAgICAgMCxcbiAgICBleHBpcmVkOiAgICAgIDEsXG4gICAgcmV2b2tlZDogICAgICAyLFxuICAgIHZhbGlkOiAgICAgICAgMyxcbiAgICBub19zZWxmX2NlcnQ6IDRcbiAgfSxcblxuICAvKiogQXJtb3IgdHlwZVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICovXG4gIGFybW9yOiB7XG4gICAgbXVsdGlwYXJ0X3NlY3Rpb246IDAsXG4gICAgbXVsdGlwYXJ0X2xhc3Q6IDEsXG4gICAgc2lnbmVkOiAyLFxuICAgIG1lc3NhZ2U6IDMsXG4gICAgcHVibGljX2tleTogNCxcbiAgICBwcml2YXRlX2tleTogNVxuICB9LFxuXG4gIC8qKiBBc3NlcnRzIHZhbGlkaXR5IGFuZCBjb252ZXJ0cyBmcm9tIHN0cmluZy9pbnRlZ2VyIHRvIGludGVnZXIuICovXG4gIHdyaXRlOiBmdW5jdGlvbih0eXBlLCBlKSB7XG4gICAgaWYgKHR5cGVvZiBlID09ICdudW1iZXInKSB7XG4gICAgICBlID0gdGhpcy5yZWFkKHR5cGUsIGUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlW2VdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0eXBlW2VdO1xuICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZW51bSB2YWx1ZS4nKTtcbiAgfSxcbiAgLyoqIENvbnZlcnRzIGZyb20gYW4gaW50ZWdlciB0byBzdHJpbmcuICovXG4gIHJlYWQ6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBmb3IgKHZhciBpIGluIHR5cGUpXG4gICAgICBpZiAodHlwZVtpXSA9PSBlKSByZXR1cm4gaTtcblxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuICB9XG59XG4iLCJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9vcGVucGdwLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5rZXkgPSByZXF1aXJlKCcuL2tleS5qcycpO1xubW9kdWxlLmV4cG9ydHMubWVzc2FnZSA9IHJlcXVpcmUoJy4vbWVzc2FnZS5qcycpO1xubW9kdWxlLmV4cG9ydHMuY2xlYXJ0ZXh0ID0gcmVxdWlyZSgnLi9jbGVhcnRleHQuanMnKTtcbm1vZHVsZS5leHBvcnRzLnV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbm1vZHVsZS5leHBvcnRzLnBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG5tb2R1bGUuZXhwb3J0cy5tcGkgPSByZXF1aXJlKCcuL3R5cGUvbXBpLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5zMmsgPSByZXF1aXJlKCcuL3R5cGUvczJrLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5rZXlpZCA9IHJlcXVpcmUoJy4vdHlwZS9rZXlpZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5lbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbm1vZHVsZS5leHBvcnRzLmNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5tb2R1bGUuZXhwb3J0cy5jcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0bycpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUga2V5ICovXG5cbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpO1xudmFyIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xudmFyIGFybW9yID0gcmVxdWlyZSgnLi9lbmNvZGluZy9hcm1vci5qcycpO1xudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBPcGVuUEdQIGtleS4gTXVzdCBjb250YWluIGEgcHJpbWFyeSBrZXkuXG4gKiBDYW4gY29udGFpbiBhZGRpdGlvbmFsIHN1YmtleXMsIHNpZ25hdHVyZXMsIHVzZXIgaWRzLCB1c2VyIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3BhY2tldGxpc3R9IHBhY2tldGxpc3QgVGhlIHBhY2tldHMgdGhhdCBmb3JtIHRoaXMga2V5XG4gKi9cblxuZnVuY3Rpb24gS2V5KHBhY2tldGxpc3QpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEtleSkpIHtcbiAgICByZXR1cm4gbmV3IEtleShwYWNrZXRsaXN0KTtcbiAgfVxuICAvLyBzYW1lIGRhdGEgYXMgaW4gcGFja2V0bGlzdCBidXQgaW4gc3RydWN0dXJlZCBmb3JtXG4gIHRoaXMucHJpbWFyeUtleSA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IG51bGw7XG4gIHRoaXMuZGlyZWN0U2lnbmF0dXJlcyA9IG51bGw7XG4gIHRoaXMudXNlcnMgPSBudWxsO1xuICB0aGlzLnN1YktleXMgPSBudWxsO1xuICB0aGlzLnBhY2tldGxpc3Qyc3RydWN0dXJlKHBhY2tldGxpc3QpO1xuICBpZiAoIXRoaXMucHJpbWFyeUtleSB8fCAhdGhpcy51c2Vycykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXk6IG5lZWQgYXQgbGVhc3Qga2V5IGFuZCB1c2VyIElEIHBhY2tldCcpO1xuICB9XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBwYWNrZXRsaXN0IHRvIHN0cnVjdHVyZWQga2V5IGRhdGFcbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH0gcGFja2V0bGlzdCBUaGUgcGFja2V0cyB0aGF0IGZvcm0gYSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS5wYWNrZXRsaXN0MnN0cnVjdHVyZSA9IGZ1bmN0aW9uKHBhY2tldGxpc3QpIHtcbiAgdmFyIHVzZXIsIHByaW1hcnlLZXlJZCwgc3ViS2V5O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhY2tldGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBzd2l0Y2ggKHBhY2tldGxpc3RbaV0udGFnKSB7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5wdWJsaWNfa2V5OlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X2tleTpcbiAgICAgICAgdGhpcy5wcmltYXJ5S2V5ID0gcGFja2V0bGlzdFtpXTtcbiAgICAgICAgcHJpbWFyeUtleUlkID0gdGhpcy5wcmltYXJ5S2V5LmdldEtleUlkKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQudXNlcmlkOlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQudXNlcl9hdHRyaWJ1dGU6XG4gICAgICAgIHVzZXIgPSBuZXcgVXNlcihwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgaWYgKCF0aGlzLnVzZXJzKSB0aGlzLnVzZXJzID0gW107XG4gICAgICAgIHRoaXMudXNlcnMucHVzaCh1c2VyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5wdWJsaWNfc3Via2V5OlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X3N1YmtleTpcbiAgICAgICAgdXNlciA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdWJLZXlzKSB0aGlzLnN1YktleXMgPSBbXTtcbiAgICAgICAgc3ViS2V5ID0gbmV3IFN1YktleShwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgdGhpcy5zdWJLZXlzLnB1c2goc3ViS2V5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5zaWduYXR1cmU6XG4gICAgICAgIHN3aXRjaCAocGFja2V0bGlzdFtpXS5zaWduYXR1cmVUeXBlKSB7XG4gICAgICAgICAgY2FzZSBlbnVtcy5zaWduYXR1cmUuY2VydF9nZW5lcmljOlxuICAgICAgICAgIGNhc2UgZW51bXMuc2lnbmF0dXJlLmNlcnRfcGVyc29uYTpcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X2Nhc3VhbDpcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X3Bvc2l0aXZlOlxuICAgICAgICAgICAgaWYgKHBhY2tldGxpc3RbaV0uaXNzdWVyS2V5SWQuZXF1YWxzKHByaW1hcnlLZXlJZCkpIHtcbiAgICAgICAgICAgICAgaWYgKCF1c2VyLnNlbGZDZXJ0aWZpY2F0aW9ucykgdXNlci5zZWxmQ2VydGlmaWNhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgdXNlci5zZWxmQ2VydGlmaWNhdGlvbnMucHVzaChwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghdXNlci5vdGhlckNlcnRpZmljYXRpb25zKSB1c2VyLm90aGVyQ2VydGlmaWNhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgdXNlci5vdGhlckNlcnRpZmljYXRpb25zLnB1c2gocGFja2V0bGlzdFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X3Jldm9jYXRpb246XG4gICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICBpZiAoIXVzZXIucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKSB1c2VyLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICB1c2VyLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucy5wdXNoKHBhY2tldGxpc3RbaV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCF0aGlzLmRpcmVjdFNpZ25hdHVyZXMpIHRoaXMuZGlyZWN0U2lnbmF0dXJlcyA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmRpcmVjdFNpZ25hdHVyZXMucHVzaChwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgZW51bXMuc2lnbmF0dXJlLmtleTpcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXJlY3RTaWduYXR1cmVzKSB0aGlzLmRpcmVjdFNpZ25hdHVyZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZGlyZWN0U2lnbmF0dXJlcy5wdXNoKHBhY2tldGxpc3RbaV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBlbnVtcy5zaWduYXR1cmUuc3Via2V5X2JpbmRpbmc6XG4gICAgICAgICAgICBzdWJLZXkuYmluZGluZ1NpZ25hdHVyZSA9IHBhY2tldGxpc3RbaV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5rZXlfcmV2b2NhdGlvbjpcbiAgICAgICAgICAgIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IHBhY2tldGxpc3RbaV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5zdWJrZXlfcmV2b2NhdGlvbjpcbiAgICAgICAgICAgIHN1YktleS5yZXZvY2F0aW9uU2lnbmF0dXJlID0gcGFja2V0bGlzdFtpXTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHN0cnVjdHVyZWQga2V5IGRhdGEgdG8gcGFja2V0bGlzdFxuICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fSBUaGUgcGFja2V0cyB0aGF0IGZvcm0gYSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMucHJpbWFyeUtleSk7XG4gIHBhY2tldGxpc3QucHVzaCh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUpO1xuICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLmRpcmVjdFNpZ25hdHVyZXMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudXNlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLnVzZXJzW2ldLnRvUGFja2V0bGlzdCgpKTtcbiAgfVxuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhY2tldGxpc3QuY29uY2F0KHRoaXMuc3ViS2V5c1tpXS50b1BhY2tldGxpc3QoKSk7XG4gICAgfSBcbiAgfVxuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKiBcbiAqIFJldHVybnMgdGhlIHByaW1hcnkga2V5IHBhY2tldCAoc2VjcmV0IG9yIHB1YmxpYylcbiAqIEByZXR1cm5zIHsobW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleXxudWxsKX0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5UGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnByaW1hcnlLZXk7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGFsbCB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIHN1YmtleSBwYWNrZXRzXG4gKiBAcmV0dXJucyB7QXJyYXk8KG1vZHVsZTpwYWNrZXQvcHVibGljX3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9zdWJrZXkpPn0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0U3Via2V5UGFja2V0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc3ViS2V5cyA9IFtdO1xuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN1YktleXMucHVzaCh0aGlzLnN1YktleXNbaV0uc3ViS2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1YktleXM7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGFsbCB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIGtleSBhbmQgc3Via2V5IHBhY2tldHNcbiAqIEByZXR1cm5zIHtBcnJheTwobW9kdWxlOnBhY2tldC9wdWJsaWNfc3Via2V5fG1vZHVsZTpwYWNrZXQvc2VjcmV0X3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5KT59IFxuICovXG5LZXkucHJvdG90eXBlLmdldEFsbEtleVBhY2tldHMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIFt0aGlzLmdldEtleVBhY2tldCgpXS5jb25jYXQodGhpcy5nZXRTdWJrZXlQYWNrZXRzKCkpO1xufTtcblxuLyoqIFxuICogUmV0dXJucyBrZXkgSURzIG9mIGFsbCBrZXkgcGFja2V0c1xuICogQHJldHVybnMge0FycmF5PG1vZHVsZTp0eXBlL2tleWlkPn0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAga2V5SWRzLnB1c2goa2V5c1tpXS5nZXRLZXlJZCgpKTtcbiAgfVxuICByZXR1cm4ga2V5SWRzO1xufTtcblxuZnVuY3Rpb24gZmluZEtleShrZXlzLCBrZXlJZHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleUlkID0ga2V5c1tpXS5nZXRLZXlJZCgpOyBcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGtleUlkLmVxdWFscyhrZXlJZHNbal0pKSB7XG4gICAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHB1YmxpYyBrZXkgcGFja2V0IGZvciBnaXZlbiBhcnJheSBvZiBrZXkgSURzXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6dHlwZS9rZXlpZD59IGtleUlkcyBcbiAqIEByZXR1cm4geyhtb2R1bGU6cGFja2V0L3B1YmxpY19zdWJrZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fG51bGwpfVxuICovXG5LZXkucHJvdG90eXBlLmdldFB1YmxpY0tleVBhY2tldCA9IGZ1bmN0aW9uKGtleUlkcykge1xuICBpZiAodGhpcy5wcmltYXJ5S2V5LnRhZyA9PSBlbnVtcy5wYWNrZXQucHVibGljX2tleSkge1xuICAgIHJldHVybiBmaW5kS2V5KHRoaXMuZ2V0QWxsS2V5UGFja2V0cygpLCBrZXlJZHMpOyAgXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gIFxufTtcblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHByaXZhdGUga2V5IHBhY2tldCBmb3IgZ2l2ZW4gYXJyYXkgb2Yga2V5IElEc1xuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOnR5cGUva2V5aWQ+fSBrZXlJZHNcbiAqIEByZXR1cm4geyhtb2R1bGU6cGFja2V0L3NlY3JldF9zdWJrZXl8bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG51bGwpfVxuICovXG5LZXkucHJvdG90eXBlLmdldFByaXZhdGVLZXlQYWNrZXQgPSBmdW5jdGlvbihrZXlJZHMpIHtcbiAgaWYgKHRoaXMucHJpbWFyeUtleS50YWcgPT0gZW51bXMucGFja2V0LnNlY3JldF9rZXkpIHtcbiAgICByZXR1cm4gZmluZEtleSh0aGlzLmdldEFsbEtleVBhY2tldHMoKSwga2V5SWRzKTsgIFxuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgdXNlcmlkc1xuICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gYXJyYXkgb2YgdXNlcmlkc1xuICovXG5LZXkucHJvdG90eXBlLmdldFVzZXJJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHVzZXJpZHMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRoaXMudXNlcnNbaV0udXNlcklkKSB7XG4gICAgICB1c2VyaWRzLnB1c2godGhpcy51c2Vyc1tpXS51c2VySWQud3JpdGUoKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyaWRzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHB1YmxpYyBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQdWJsaWMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucHJpbWFyeUtleS50YWcgPT0gZW51bXMucGFja2V0LnB1YmxpY19rZXk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQcml2YXRlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnByaW1hcnlLZXkudGFnID09IGVudW1zLnBhY2tldC5zZWNyZXRfa2V5O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGtleSBhcyBwdWJsaWMga2V5IChzaGFsbG93IGNvcHkpXG4gKiBAcmV0dXJuIHttb2R1bGU6a2V5fktleX0gbmV3IHB1YmxpYyBLZXlcbiAqL1xuS2V5LnByb3RvdHlwZS50b1B1YmxpYyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICB2YXIga2V5UGFja2V0cyA9IHRoaXMudG9QYWNrZXRsaXN0KCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5UGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgIHN3aXRjaCAoa2V5UGFja2V0c1tpXS50YWcpIHtcbiAgICAgIGNhc2UgZW51bXMucGFja2V0LnNlY3JldF9rZXk6XG4gICAgICAgIHZhciBieXRlcyA9IGtleVBhY2tldHNbaV0ud3JpdGVQdWJsaWNLZXkoKTtcbiAgICAgICAgdmFyIHB1YktleVBhY2tldCA9IG5ldyBwYWNrZXQucHVibGljX2tleSgpO1xuICAgICAgICBwdWJLZXlQYWNrZXQucmVhZChieXRlcyk7XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChwdWJLZXlQYWNrZXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgZW51bXMucGFja2V0LnNlY3JldF9zdWJrZXk6XG4gICAgICAgIHZhciBieXRlcyA9IGtleVBhY2tldHNbaV0ud3JpdGVQdWJsaWNLZXkoKTtcbiAgICAgICAgdmFyIHB1YlN1YmtleVBhY2tldCA9IG5ldyBwYWNrZXQucHVibGljX3N1YmtleSgpO1xuICAgICAgICBwdWJTdWJrZXlQYWNrZXQucmVhZChieXRlcyk7XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChwdWJTdWJrZXlQYWNrZXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChrZXlQYWNrZXRzW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIGtleVxuICogQHJldHVybiB7U3RyaW5nfSBBU0NJSSBhcm1vclxuICovXG5LZXkucHJvdG90eXBlLmFybW9yID0gZnVuY3Rpb24oKSB7XG4gIHZhciB0eXBlID0gdGhpcy5pc1B1YmxpYygpID8gZW51bXMuYXJtb3IucHVibGljX2tleSA6IGVudW1zLmFybW9yLnByaXZhdGVfa2V5O1xuICByZXR1cm4gYXJtb3IuZW5jb2RlKHR5cGUsIHRoaXMudG9QYWNrZXRsaXN0KCkud3JpdGUoKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgZmlyc3Qga2V5IHBhY2tldCB0aGF0IGlzIGF2YWlsYWJsZSBmb3Igc2lnbmluZ1xuICogQHJldHVybiB7KG1vZHVsZTpwYWNrZXQvc2VjcmV0X3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bnVsbCl9IGtleSBwYWNrZXQgb3IgbnVsbCBpZiBubyBzaWduaW5nIGtleSBoYXMgYmVlbiBmb3VuZFxuICovXG5LZXkucHJvdG90eXBlLmdldFNpZ25pbmdLZXlQYWNrZXQgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNQdWJsaWMoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTmVlZCBwcml2YXRlIGtleSBmb3Igc2lnbmluZycpO1xuICB9XG4gIHZhciBwcmltYXJ5VXNlciA9IHRoaXMuZ2V0UHJpbWFyeVVzZXIoKTtcbiAgaWYgKHByaW1hcnlVc2VyICYmIFxuICAgICAgaXNWYWxpZFNpZ25pbmdLZXlQYWNrZXQodGhpcy5wcmltYXJ5S2V5LCBwcmltYXJ5VXNlci5zZWxmQ2VydGlmaWNhdGUpKSB7XG4gICAgcmV0dXJuIHRoaXMucHJpbWFyeUtleTtcbiAgfVxuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLnN1YktleXNbaV0uaXNWYWxpZFNpZ25pbmdLZXkodGhpcy5wcmltYXJ5S2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdWJLZXlzW2ldLnN1YktleTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgcHJlZmVycmVkIHNpZ25hdHVyZSBoYXNoIGFsZ29yaXRobSBvZiB0aGlzIGtleVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5LZXkucHJvdG90eXBlLmdldFByZWZlcnJlZEhhc2hBbGdvcml0aG0gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHByaW1hcnlVc2VyID0gdGhpcy5nZXRQcmltYXJ5VXNlcigpO1xuICBpZiAocHJpbWFyeVVzZXIgJiYgcHJpbWFyeVVzZXIuc2VsZkNlcnRpZmljYXRlLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zKSB7XG4gICAgcmV0dXJuIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtc1swXTtcbiAgfVxuICByZXR1cm4gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRFbmNyeXB0aW9uS2V5UGFja2V0KGtleVBhY2tldCwgc2lnbmF0dXJlKSB7XG4gIHJldHVybiBrZXlQYWNrZXQuYWxnb3JpdGhtICE9PSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgZW51bXMucHVibGljS2V5LmRzYSkgJiZcbiAgICAgICAgIGtleVBhY2tldC5hbGdvcml0aG0gIT09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkucnNhX3NpZ24pICYmXG4gICAgICAgICAoKHNpZ25hdHVyZS5rZXlGbGFncyAmIGVudW1zLmtleUZsYWdzLmVuY3J5cHRfY29tbXVuaWNhdGlvbikgIT09IDAgfHxcbiAgICAgICAgICAoc2lnbmF0dXJlLmtleUZsYWdzICYgZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9zdG9yYWdlKSAhPT0gMCB8fFxuICAgICAgICAgICFzaWduYXR1cmUua2V5RmxhZ3MpO1xufTtcblxuZnVuY3Rpb24gaXNWYWxpZFNpZ25pbmdLZXlQYWNrZXQoa2V5UGFja2V0LCBzaWduYXR1cmUpIHtcbiAgcmV0dXJuIChrZXlQYWNrZXQuYWxnb3JpdGhtID09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkuZHNhKSB8fFxuICAgICAgICAgIGtleVBhY2tldC5hbGdvcml0aG0gPT0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGVudW1zLnB1YmxpY0tleS5yc2Ffc2lnbikgfHxcbiAgICAgICAgICBrZXlQYWNrZXQuYWxnb3JpdGhtID09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkucnNhX2VuY3J5cHRfc2lnbikpICYmXG4gICAgICAgICAoKHNpZ25hdHVyZS5rZXlGbGFncyAmIGVudW1zLmtleUZsYWdzLnNpZ25fZGF0YSkgIT09IDAgfHxcbiAgICAgICAgICAhc2lnbmF0dXJlLmtleUZsYWdzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgdmFsaWQgZW5jcnlwdGlvbiBrZXkgcGFja2V0IGZvciB0aGlzIGtleVxuICogQHJldHVybnMgeyhtb2R1bGU6cGFja2V0L3B1YmxpY19zdWJrZXl8bW9kdWxlOnBhY2tldC9zZWNyZXRfc3Via2V5fG1vZHVsZTpwYWNrZXQvc2VjcmV0X2tleXxtb2R1bGU6cGFja2V0L3B1YmxpY19rZXl8bnVsbCl9IGtleSBwYWNrZXQgb3IgbnVsbCBpZiBubyBlbmNyeXB0aW9uIGtleSBoYXMgYmVlbiBmb3VuZFxuICovXG5LZXkucHJvdG90eXBlLmdldEVuY3J5cHRpb25LZXlQYWNrZXQgPSBmdW5jdGlvbigpIHtcbiAgLy8gVjQ6IGJ5IGNvbnZlbnRpb24gc3Via2V5cyBhcmUgcHJlZmVyZWQgZm9yIGVuY3J5cHRpb24gc2VydmljZVxuICAvLyBWMzoga2V5cyBNVVNUIE5PVCBoYXZlIHN1YmtleXNcbiAgaWYgKHRoaXMuc3ViS2V5cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5zdWJLZXlzW2ldLmlzVmFsaWRFbmNyeXB0aW9uS2V5KHRoaXMucHJpbWFyeUtleSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViS2V5c1tpXS5zdWJLZXk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIGlmIG5vIHZhbGlkIHN1YmtleSBmb3IgZW5jcnlwdGlvbiwgZXZhbHVhdGUgcHJpbWFyeSBrZXlcbiAgdmFyIHByaW1hcnlVc2VyID0gdGhpcy5nZXRQcmltYXJ5VXNlcigpO1xuICBpZiAocHJpbWFyeVVzZXIgJiYgXG4gICAgICBpc1ZhbGlkRW5jcnlwdGlvbktleVBhY2tldCh0aGlzLnByaW1hcnlLZXksIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZSkpIHtcbiAgICByZXR1cm4gdGhpcy5wcmltYXJ5S2V5O1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBEZWNyeXB0cyBhbGwgc2VjcmV0IGtleSBhbmQgc3Via2V5IHBhY2tldHNcbiAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3BocmFzZSBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIGtleSBhbmQgc3Via2V5IHBhY2tldHMgZGVjcnlwdGVkIHN1Y2Nlc3NmdWxseVxuICovXG5LZXkucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gIGlmICh0aGlzLmlzUHJpdmF0ZSgpKSB7XG4gICAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzdWNjZXNzID0ga2V5c1tpXS5kZWNyeXB0KHBhc3NwaHJhc2UpO1xuICAgICAgaWYgKCFzdWNjZXNzKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdGhpbmcgdG8gZGVjcnlwdCBpbiBhIHB1YmxpYyBrZXlcIik7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIERlY3J5cHRzIHNwZWNpZmljIGtleSBwYWNrZXRzIGJ5IGtleSBJRFxuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOnR5cGUva2V5aWQ+fSBrZXlJZHNcbiAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3BocmFzZSBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIGtleSBwYWNrZXRzIGRlY3J5cHRlZCBzdWNjZXNzZnVsbHlcbiAqL1xuS2V5LnByb3RvdHlwZS5kZWNyeXB0S2V5UGFja2V0ID0gZnVuY3Rpb24oa2V5SWRzLCBwYXNzcGhyYXNlKSB7XG4gIGlmICh0aGlzLmlzUHJpdmF0ZSgpKSB7XG4gICAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXlJZCA9IGtleXNbaV0uZ2V0S2V5SWQoKTsgXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoa2V5SWQuZXF1YWxzKGtleUlkc1tqXSkpIHtcbiAgICAgICAgICB2YXIgc3VjY2VzcyA9IGtleXNbaV0uZGVjcnlwdChwYXNzcGhyYXNlKTtcbiAgICAgICAgICBpZiAoIXN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3RoaW5nIHRvIGRlY3J5cHQgaW4gYSBwdWJsaWMga2V5XCIpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgcHJpbWFyeSBrZXkuIENoZWNrcyBmb3IgcmV2b2NhdGlvbiBzaWduYXR1cmVzLCBleHBpcmF0aW9uIHRpbWVcbiAqIGFuZCB2YWxpZCBzZWxmIHNpZ25hdHVyZVxuICogQHJldHVybiB7bW9kdWxlOmVudW1zLmtleVN0YXR1c30gVGhlIHN0YXR1cyBvZiB0aGUgcHJpbWFyeSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS52ZXJpZnlQcmltYXJ5S2V5ID0gZnVuY3Rpb24oKSB7XG4gIC8vIGNoZWNrIHJldm9jYXRpb24gc2lnbmF0dXJlXG4gIGlmICh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUgJiYgIXRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS5pc0V4cGlyZWQoKSAmJiBcbiAgICAgKHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS52ZXJpZmllZCB8fCBcbiAgICAgIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS52ZXJpZnkodGhpcy5wcmltYXJ5S2V5LCB7a2V5OiB0aGlzLnByaW1hcnlLZXl9KSkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLnJldm9rZWQ7XG4gIH1cbiAgLy8gY2hlY2sgVjMgZXhwaXJhdGlvbiB0aW1lXG4gIGlmICh0aGlzLnByaW1hcnlLZXkudmVyc2lvbiA9PSAzICYmIHRoaXMucHJpbWFyeUtleS5leHBpcmF0aW9uVGltZVYzICE9PSAwICYmXG4gICAgRGF0ZS5ub3coKSA+ICh0aGlzLnByaW1hcnlLZXkuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnByaW1hcnlLZXkuZXhwaXJhdGlvblRpbWVWMyoyNCozNjAwKjEwMDApKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5leHBpcmVkO1xuICB9XG4gIC8vIGNoZWNrIGZvciBhdCBsZWFzdCBvbmUgc2VsZiBzaWduYXR1cmUuIFNlbGYgc2lnbmF0dXJlIG9mIHVzZXIgSUQgbm90IG1hbmRhdG9yeVxuICAvLyBTZWUgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg4MCNzZWN0aW9uLTExLjFcbiAgdmFyIHNlbGZTaWduZWQgPSBmYWxzZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRoaXMudXNlcnNbaV0udXNlcklkICYmIHRoaXMudXNlcnNbaV0uc2VsZkNlcnRpZmljYXRpb25zKSB7XG4gICAgICBzZWxmU2lnbmVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKCFzZWxmU2lnbmVkKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5ub19zZWxmX2NlcnQ7XG4gIH1cbiAgLy8gY2hlY2sgZm9yIHZhbGlkIHNlbGYgc2lnbmF0dXJlXG4gIHZhciBwcmltYXJ5VXNlciA9IHRoaXMuZ2V0UHJpbWFyeVVzZXIoKTtcbiAgaWYgKCFwcmltYXJ5VXNlcikge1xuICAgIHJldHVybiBlbnVtcy5rZXlTdGF0dXMuaW52YWxpZDtcbiAgfVxuICAvLyBjaGVjayBWNCBleHBpcmF0aW9uIHRpbWVcbiAgaWYgKHRoaXMucHJpbWFyeUtleS52ZXJzaW9uID09IDQgJiYgcHJpbWFyeVVzZXIuc2VsZkNlcnRpZmljYXRlLmtleU5ldmVyRXhwaXJlcyA9PT0gZmFsc2UgJiZcbiAgICBEYXRlLm5vdygpID4gKHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5jcmVhdGVkLmdldFRpbWUoKSArIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5rZXlFeHBpcmF0aW9uVGltZSoxMDAwKSkge1xuICAgIHJldHVybiBlbnVtcy5rZXlTdGF0dXMuZXhwaXJlZDtcbiAgfVxuICByZXR1cm4gZW51bXMua2V5U3RhdHVzLnZhbGlkO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHByaW1hcnkgdXNlciBhbmQgbW9zdCBzaWduaWZpY2FudCAobGF0ZXN0IHZhbGlkKSBzZWxmIHNpZ25hdHVyZVxuICogLSBpZiBtdWx0aXBsZSB1c2VycyBhcmUgbWFya2VkIGFzIHByaW1hcnkgdXNlcnMgcmV0dXJucyB0aGUgb25lIHdpdGggdGhlIGxhdGVzdCBzZWxmIHNpZ25hdHVyZVxuICogLSBpZiBubyBwcmltYXJ5IHVzZXIgaXMgZm91bmQgcmV0dXJucyB0aGUgdXNlciB3aXRoIHRoZSBsYXRlc3Qgc2VsZiBzaWduYXR1cmVcbiAqIEByZXR1cm4ge3t1c2VyOiBBcnJheTxtb2R1bGU6cGFja2V0L1VzZXI+LCBzZWxmQ2VydGlmaWNhdGU6IEFycmF5PG1vZHVsZTpwYWNrZXQvc2lnbmF0dXJlPn19IFRoZSBwcmltYXJ5IHVzZXIgYW5kIHRoZSBzZWxmIHNpZ25hdHVyZVxuICovXG5LZXkucHJvdG90eXBlLmdldFByaW1hcnlVc2VyID0gZnVuY3Rpb24oKSB7XG4gIHZhciB1c2VyID0gbnVsbDtcbiAgdmFyIHVzZXJTZWxmQ2VydDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCF0aGlzLnVzZXJzW2ldLnVzZXJJZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBzZWxmQ2VydCA9IHRoaXMudXNlcnNbaV0uZ2V0VmFsaWRTZWxmQ2VydGlmaWNhdGUodGhpcy5wcmltYXJ5S2V5KTtcbiAgICBpZiAoIXNlbGZDZXJ0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCF1c2VyIHx8IFxuICAgICAgICAhdXNlclNlbGZDZXJ0LmlzUHJpbWFyeVVzZXJJRCAmJiBzZWxmQ2VydC5pc1ByaW1hcnlVc2VySUQgfHxcbiAgICAgICAgIHVzZXJTZWxmQ2VydC5jcmVhdGVkIDwgc2VsZkNlcnQuY3JlYXRlZCkge1xuICAgICAgdXNlciA9IHRoaXMudXNlcnNbaV07XG4gICAgICB1c2VyU2VsZkNlcnQgPSBzZWxmQ2VydDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXIgPyB7dXNlcjogdXNlciwgc2VsZkNlcnRpZmljYXRlOiB1c2VyU2VsZkNlcnR9IDogbnVsbDtcbn1cblxuLy8gVE9ET1xuS2V5LnByb3RvdHlwZS5yZXZva2UgPSBmdW5jdGlvbigpIHtcblxufTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIHVzZXIgSUQgb3IgYXR0cmlidXRlIHBhY2tldCBhbmQgdGhlIHJlbGV2YW50IHNpZ25hdHVyZXMuXG4gKi9cbmZ1bmN0aW9uIFVzZXIodXNlclBhY2tldCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVXNlcikpIHtcbiAgICByZXR1cm4gbmV3IFVzZXIodXNlclBhY2tldCk7XG4gIH1cbiAgdGhpcy51c2VySWQgPSB1c2VyUGFja2V0LnRhZyA9PSBlbnVtcy5wYWNrZXQudXNlcmlkID8gdXNlclBhY2tldCA6IG51bGw7XG4gIHRoaXMudXNlckF0dHJpYnV0ZSA9IHVzZXJQYWNrZXQudGFnID09IGVudW1zLnBhY2tldC51c2VyX2F0dHJpYnV0ZSA/IHVzZXJQYWNrZXQgOiBudWxsXG4gIHRoaXMuc2VsZkNlcnRpZmljYXRpb25zID0gbnVsbDtcbiAgdGhpcy5vdGhlckNlcnRpZmljYXRpb25zID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uQ2VydGlmaWNhdGlvbnMgPSBudWxsO1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybXMgc3RydWN0dXJlZCB1c2VyIGRhdGEgdG8gcGFja2V0bGlzdFxuICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fVxuICovXG5Vc2VyLnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMudXNlcklkIHx8IHRoaXMudXNlckF0dHJpYnV0ZSk7XG4gIHBhY2tldGxpc3QuY29uY2F0KHRoaXMucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKTtcbiAgcGFja2V0bGlzdC5jb25jYXQodGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMpO1xuICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLm90aGVyQ2VydGlmaWNhdGlvbnMpO1xuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgc2VsZiBzaWduYXR1cmUgb2YgdGhlIHVzZXIgaXMgcmV2b2tlZFxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zaWduYXR1cmV9ICAgICAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZVxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0gcHJpbWFyeUtleSAgVGhlIHByaW1hcnkga2V5IHBhY2tldFxuICogQHJldHVybiB7Qm9vbGVhbn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRydWUgaWYgdGhlIGNlcnRpZmljYXRlIGlzIHJldm9rZWRcbiAqL1xuVXNlci5wcm90b3R5cGUuaXNSZXZva2VkID0gZnVuY3Rpb24oY2VydGlmaWNhdGUsIHByaW1hcnlLZXkpIHtcbiAgaWYgKHRoaXMucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHJldHVybiB0aGlzLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucy5zb21lKGZ1bmN0aW9uKHJldkNlcnQpIHtcbiAgICAgICAgICAgICByZXR1cm4gcmV2Q2VydC5pc3N1ZXJLZXlJZC5lcXVhbHMoY2VydGlmaWNhdGUuaXNzdWVyS2V5SWQpICYmXG4gICAgICAgICAgICAgICAgICAgICFyZXZDZXJ0LmlzRXhwaXJlZCgpICYmIFxuICAgICAgICAgICAgICAgICAgICAocmV2Q2VydC52ZXJpZmllZCB8fCBcbiAgICAgICAgICAgICAgICAgICAgIHJldkNlcnQudmVyaWZ5KHByaW1hcnlLZXksIHt1c2VyaWQ6IHRoYXQudXNlcklkIHx8IHRoYXQudXNlckF0dHJpYnV0ZSwga2V5OiBwcmltYXJ5S2V5fSkpO1xuICAgICAgICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtb3N0IHNpZ25pZmljYW50IChsYXRlc3QgdmFsaWQpIHNlbGYgc2lnbmF0dXJlIG9mIHRoZSB1c2VyXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fSBwcmltYXJ5S2V5IFRoZSBwcmltYXJ5IGtleSBwYWNrZXRcbiAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvc2lnbmF0dXJlfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgc2VsZiBzaWduYXR1cmVcbiAqL1xuVXNlci5wcm90b3R5cGUuZ2V0VmFsaWRTZWxmQ2VydGlmaWNhdGUgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIGlmICghdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgdmFsaWRDZXJ0ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGhpcy5pc1Jldm9rZWQodGhpcy5zZWxmQ2VydGlmaWNhdGlvbnNbaV0sIHByaW1hcnlLZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS5pc0V4cGlyZWQoKSAmJlxuICAgICAgICh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS52ZXJpZmllZCB8fCBcbiAgICAgICAgdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnNbaV0udmVyaWZ5KHByaW1hcnlLZXksIHt1c2VyaWQ6IHRoaXMudXNlcklkIHx8IHRoaXMudXNlckF0dHJpYnV0ZSwga2V5OiBwcmltYXJ5S2V5fSkpKSB7XG4gICAgICB2YWxpZENlcnQucHVzaCh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXSk7XG4gICAgfVxuICB9XG4gIC8vIG1vc3QgcmVjZW50IGZpcnN0XG4gIHZhbGlkQ2VydCA9IHZhbGlkQ2VydC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICBhID0gYS5jcmVhdGVkO1xuICAgIGIgPSBiLmNyZWF0ZWQ7XG4gICAgcmV0dXJuIGE+YiA/IC0xIDogYTxiID8gMSA6IDA7XG4gIH0pO1xuICByZXR1cm4gdmFsaWRDZXJ0WzBdO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgVXNlci4gQ2hlY2tzIGZvciBleGlzdGVuY2Ugb2Ygc2VsZiBzaWduYXR1cmVzLCByZXZvY2F0aW9uIHNpZ25hdHVyZXNcbiAqIGFuZCB2YWxpZGl0eSBvZiBzZWxmIHNpZ25hdHVyZVxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0gcHJpbWFyeUtleSBUaGUgcHJpbWFyeSBrZXkgcGFja2V0XG4gKiBAcmV0dXJuIHttb2R1bGU6ZW51bXMua2V5U3RhdHVzfSBzdGF0dXMgb2YgdXNlciAgICBcbiAqL1xuVXNlci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHJpbWFyeUtleSkge1xuICBpZiAoIXRoaXMuc2VsZkNlcnRpZmljYXRpb25zKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5ub19zZWxmX2NlcnQ7XG4gIH1cbiAgdmFyIHN0YXR1cztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNlbGZDZXJ0aWZpY2F0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0aGlzLmlzUmV2b2tlZCh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXSwgcHJpbWFyeUtleSkpIHtcbiAgICAgIHN0YXR1cyA9IGVudW1zLmtleVN0YXR1cy5yZXZva2VkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICghKHRoaXMuc2VsZkNlcnRpZmljYXRpb25zW2ldLnZlcmlmaWVkIHx8IFxuICAgICAgICB0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS52ZXJpZnkocHJpbWFyeUtleSwge3VzZXJpZDogdGhpcy51c2VySWQgfHwgdGhpcy51c2VyQXR0cmlidXRlLCBrZXk6IHByaW1hcnlLZXl9KSkpIHtcbiAgICAgIHN0YXR1cyA9IGVudW1zLmtleVN0YXR1cy5pbnZhbGlkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS5pc0V4cGlyZWQoKSkge1xuICAgICAgc3RhdHVzID0gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgc3RhdHVzID0gZW51bXMua2V5U3RhdHVzLnZhbGlkO1xuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiBzdGF0dXM7XG59O1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBzdWJrZXkgcGFja2V0IGFuZCB0aGUgcmVsZXZhbnQgc2lnbmF0dXJlcy5cbiAqL1xuZnVuY3Rpb24gU3ViS2V5KHN1YktleVBhY2tldCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3ViS2V5KSkge1xuICAgIHJldHVybiBuZXcgU3ViS2V5KHN1YktleVBhY2tldCk7XG4gIH1cbiAgdGhpcy5zdWJLZXkgPSBzdWJLZXlQYWNrZXQ7XG4gIHRoaXMuYmluZGluZ1NpZ25hdHVyZSA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IG51bGw7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBzdHJ1Y3R1cmVkIHN1YmtleSBkYXRhIHRvIHBhY2tldGxpc3RcbiAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH1cbiAqL1xuU3ViS2V5LnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMuc3ViS2V5KTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSk7XG4gIHBhY2tldGxpc3QucHVzaCh0aGlzLmJpbmRpbmdTaWduYXR1cmUpO1xuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdWJrZXkgY2FuIGJlIHVzZWQgZm9yIGVuY3J5cHRpb25cbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvc2VjcmV0X2tleXxtb2R1bGU6cGFja2V0L3B1YmxpY19rZXl9ICBwcmltYXJ5S2V5IFRoZSBwcmltYXJ5IGtleSBwYWNrZXRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblN1YktleS5wcm90b3R5cGUuaXNWYWxpZEVuY3J5cHRpb25LZXkgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIHJldHVybiB0aGlzLnZlcmlmeShwcmltYXJ5S2V5KSA9PSBlbnVtcy5rZXlTdGF0dXMudmFsaWQgJiZcbiAgICAgICAgIGlzVmFsaWRFbmNyeXB0aW9uS2V5UGFja2V0KHRoaXMuc3ViS2V5LCB0aGlzLmJpbmRpbmdTaWduYXR1cmUpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN1YmtleSBjYW4gYmUgdXNlZCBmb3Igc2lnbmluZyBvZiBkYXRhXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fSAgcHJpbWFyeUtleSBUaGUgcHJpbWFyeSBrZXkgcGFja2V0XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5TdWJLZXkucHJvdG90eXBlLmlzVmFsaWRTaWduaW5nS2V5ID0gZnVuY3Rpb24ocHJpbWFyeUtleSkge1xuICByZXR1cm4gdGhpcy52ZXJpZnkocHJpbWFyeUtleSkgPT0gZW51bXMua2V5U3RhdHVzLnZhbGlkICYmXG4gICAgICAgICBpc1ZhbGlkU2lnbmluZ0tleVBhY2tldCh0aGlzLnN1YktleSwgdGhpcy5iaW5kaW5nU2lnbmF0dXJlKTtcbn07XG5cbi8qKlxuICogVmVyaWZ5IHN1YmtleS4gQ2hlY2tzIGZvciByZXZvY2F0aW9uIHNpZ25hdHVyZXMsIGV4cGlyYXRpb24gdGltZVxuICogYW5kIHZhbGlkIGJpbmRpbmcgc2lnbmF0dXJlXG4gKiBAcmV0dXJuIHttb2R1bGU6ZW51bXMua2V5U3RhdHVzfSBUaGUgc3RhdHVzIG9mIHRoZSBzdWJrZXlcbiAqL1xuU3ViS2V5LnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIC8vIGNoZWNrIHN1YmtleSByZXZvY2F0aW9uIHNpZ25hdHVyZVxuICBpZiAodGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlICYmICF0aGlzLnJldm9jYXRpb25TaWduYXR1cmUuaXNFeHBpcmVkKCkgJiYgXG4gICAgICh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUudmVyaWZpZWQgfHwgXG4gICAgICB0aGlzLnJldm9jYXRpb25TaWduYXR1cmUudmVyaWZ5KHByaW1hcnlLZXksIHtrZXk6IHRoaXMuc3ViS2V5fSkpKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5yZXZva2VkO1xuICB9XG4gIC8vIGNoZWNrIFYzIGV4cGlyYXRpb24gdGltZVxuICBpZiAodGhpcy5zdWJLZXkudmVyc2lvbiA9PSAzICYmIHRoaXMuc3ViS2V5LmV4cGlyYXRpb25UaW1lVjMgIT09IDAgJiZcbiAgICAgIERhdGUubm93KCkgPiAodGhpcy5zdWJLZXkuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnN1YktleS5leHBpcmF0aW9uVGltZVYzKjI0KjM2MDAqMTAwMCkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gIH1cbiAgLy8gY2hlY2sgc3Via2V5IGJpbmRpbmcgc2lnbmF0dXJlXG4gIGlmICghdGhpcy5iaW5kaW5nU2lnbmF0dXJlKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5pbnZhbGlkO1xuICB9XG4gIGlmICh0aGlzLmJpbmRpbmdTaWduYXR1cmUuaXNFeHBpcmVkKCkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gIH1cbiAgaWYgKCEodGhpcy5iaW5kaW5nU2lnbmF0dXJlLnZlcmlmaWVkIHx8XG4gICAgICAgIHRoaXMuYmluZGluZ1NpZ25hdHVyZS52ZXJpZnkocHJpbWFyeUtleSwge2tleTogcHJpbWFyeUtleSwgYmluZDogdGhpcy5zdWJLZXl9KSkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmludmFsaWQ7XG4gIH1cbiAgLy8gY2hlY2sgVjQgZXhwaXJhdGlvbiB0aW1lXG4gIGlmICh0aGlzLnN1YktleS52ZXJzaW9uID09IDQgJiZcbiAgICAgIHRoaXMuYmluZGluZ1NpZ25hdHVyZS5rZXlOZXZlckV4cGlyZXMgPT09IGZhbHNlICYmXG4gICAgICBEYXRlLm5vdygpID4gKHRoaXMuc3ViS2V5LmNyZWF0ZWQuZ2V0VGltZSgpICsgdGhpcy5iaW5kaW5nU2lnbmF0dXJlLmtleUV4cGlyYXRpb25UaW1lKjEwMDApKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5leHBpcmVkO1xuICB9XG4gIHJldHVybiBlbnVtcy5rZXlTdGF0dXMudmFsaWQ7XG59O1xuXG4vKipcbiAqIFJlYWRzIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZCByZXR1cm5zIG9uZSBvciBtdWx0aXBsZSBrZXkgb2JqZWN0c1xuICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWRUZXh0IHRleHQgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJuIHt7a2V5czogQXJyYXk8bW9kdWxlOmtleX5LZXk+LCBlcnI6IChBcnJheTxFcnJvcj58bnVsbCl9fSByZXN1bHQgb2JqZWN0IHdpdGgga2V5IGFuZCBlcnJvciBhcnJheXNcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICByZXN1bHQua2V5cyA9IFtdO1xuICB0cnkge1xuICAgIHZhciBpbnB1dCA9IGFybW9yLmRlY29kZShhcm1vcmVkVGV4dCk7XG4gICAgaWYgKCEoaW5wdXQudHlwZSA9PSBlbnVtcy5hcm1vci5wdWJsaWNfa2V5IHx8IGlucHV0LnR5cGUgPT0gZW51bXMuYXJtb3IucHJpdmF0ZV9rZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FybW9yZWQgdGV4dCBub3Qgb2YgdHlwZSBrZXknKTtcbiAgICB9XG4gICAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQuZGF0YSk7XG4gICAgdmFyIGtleUluZGV4ID0gcGFja2V0bGlzdC5pbmRleE9mVGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5LCBlbnVtcy5wYWNrZXQuc2VjcmV0X2tleSk7XG4gICAgaWYgKGtleUluZGV4Lmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGtleSBwYWNrZXQgZm91bmQgaW4gYXJtb3JlZCB0ZXh0JylcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlJbmRleC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG9uZUtleUxpc3QgPSBwYWNrZXRsaXN0LnNsaWNlKGtleUluZGV4W2ldLCBrZXlJbmRleFtpICsgMV0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIG5ld0tleSA9IG5ldyBLZXkob25lS2V5TGlzdCk7XG4gICAgICAgIHJlc3VsdC5rZXlzLnB1c2gobmV3S2V5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVzdWx0LmVyciA9IHJlc3VsdC5lcnIgfHwgW107XG4gICAgICAgIHJlc3VsdC5lcnIucHVzaChlKTsgXG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgcmVzdWx0LmVyciA9IHJlc3VsdC5lcnIgfHwgW107XG4gICAgcmVzdWx0LmVyci5wdXNoKGUpOyBcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIG5ldyBPcGVuUEdQIGtleS4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgUlNBIGtleXMuXG4gKiBQcmltYXJ5IGFuZCBzdWJrZXkgd2lsbCBiZSBvZiBzYW1lIHR5cGUuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgICAgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0EgaXMgMS4gU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi05LjFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyAgICBudW1iZXIgb2YgYml0cyBmb3IgdGhlIGtleSBjcmVhdGlvbi5cbiAqIEBwYXJhbSB7U3RyaW5nfSAgdXNlcklkICAgICBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiBcIlVzZXIgTmFtZSA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gKiBAcGFyYW0ge1N0cmluZ30gIHBhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBlbmNyeXB0IHRoZSByZXN1bHRpbmcgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge21vZHVsZTprZXl+S2V5fVxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZShrZXlUeXBlLCBudW1CaXRzLCB1c2VySWQsIHBhc3NwaHJhc2UpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcblxuICB2YXIgc2VjcmV0S2V5UGFja2V0ID0gbmV3IHBhY2tldC5zZWNyZXRfa2V5KCk7XG4gIHNlY3JldEtleVBhY2tldC5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwga2V5VHlwZSk7XG4gIHNlY3JldEtleVBhY2tldC5nZW5lcmF0ZShudW1CaXRzKTtcbiAgc2VjcmV0S2V5UGFja2V0LmVuY3J5cHQocGFzc3BocmFzZSk7XG5cbiAgdmFyIHVzZXJJZFBhY2tldCA9IG5ldyBwYWNrZXQudXNlcmlkKCk7XG4gIHVzZXJJZFBhY2tldC5yZWFkKHVzZXJJZCk7XG5cbiAgdmFyIGRhdGFUb1NpZ24gPSB7fTtcbiAgZGF0YVRvU2lnbi51c2VyaWQgPSB1c2VySWRQYWNrZXQ7XG4gIGRhdGFUb1NpZ24ua2V5ID0gc2VjcmV0S2V5UGFja2V0O1xuICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgc2lnbmF0dXJlUGFja2V0LnNpZ25hdHVyZVR5cGUgPSBlbnVtcy5zaWduYXR1cmUuY2VydF9nZW5lcmljO1xuICBzaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0ga2V5VHlwZTtcbiAgLy9UT0RPIHdlIHNob3VsZCBsb2FkIHByZWZlcnJlZCBoYXNoIGZyb20gY29uZmlnLCBvciBhcyBpbnB1dCB0byB0aGlzIGZ1bmN0aW9uXG4gIHNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gZW51bXMuaGFzaC5zaGEyNTY7XG4gIHNpZ25hdHVyZVBhY2tldC5rZXlGbGFncyA9IFtlbnVtcy5rZXlGbGFncy5jZXJ0aWZ5X2tleXMgfCBlbnVtcy5rZXlGbGFncy5zaWduX2RhdGFdO1xuICBzaWduYXR1cmVQYWNrZXQuc2lnbihzZWNyZXRLZXlQYWNrZXQsIGRhdGFUb1NpZ24pO1xuXG4gIHZhciBzZWNyZXRTdWJrZXlQYWNrZXQgPSBuZXcgcGFja2V0LnNlY3JldF9zdWJrZXkoKTtcbiAgc2VjcmV0U3Via2V5UGFja2V0LmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBrZXlUeXBlKTtcbiAgc2VjcmV0U3Via2V5UGFja2V0LmdlbmVyYXRlKG51bUJpdHMpO1xuICBzZWNyZXRTdWJrZXlQYWNrZXQuZW5jcnlwdChwYXNzcGhyYXNlKTtcblxuICBkYXRhVG9TaWduID0ge307XG4gIGRhdGFUb1NpZ24ua2V5ID0gc2VjcmV0S2V5UGFja2V0O1xuICBkYXRhVG9TaWduLmJpbmQgPSBzZWNyZXRTdWJrZXlQYWNrZXQ7XG4gIHZhciBzdWJrZXlTaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQuc2lnbmF0dXJlVHlwZSA9IGVudW1zLnNpZ25hdHVyZS5zdWJrZXlfYmluZGluZztcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IGtleVR5cGU7XG4gIC8vVE9ETyB3ZSBzaG91bGQgbG9hZCBwcmVmZXJyZWQgaGFzaCBmcm9tIGNvbmZpZywgb3IgYXMgaW5wdXQgdG8gdGhpcyBmdW5jdGlvblxuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGVudW1zLmhhc2guc2hhMjU2O1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQua2V5RmxhZ3MgPSBbZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9jb21tdW5pY2F0aW9uIHwgZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9zdG9yYWdlXTtcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LnNpZ24oc2VjcmV0S2V5UGFja2V0LCBkYXRhVG9TaWduKTtcblxuICBwYWNrZXRsaXN0LnB1c2goc2VjcmV0S2V5UGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHVzZXJJZFBhY2tldCk7XG4gIHBhY2tldGxpc3QucHVzaChzaWduYXR1cmVQYWNrZXQpO1xuICBwYWNrZXRsaXN0LnB1c2goc2VjcmV0U3Via2V5UGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHN1YmtleVNpZ25hdHVyZVBhY2tldCk7XG5cbiAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG59XG5cbmV4cG9ydHMuS2V5ID0gS2V5O1xuZXhwb3J0cy5yZWFkQXJtb3JlZCA9IHJlYWRBcm1vcmVkO1xuZXhwb3J0cy5nZW5lcmF0ZSA9IGdlbmVyYXRlO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgbWVzc2FnZSAqL1xuXG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbnZhciBhcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpO1xudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4vY3J5cHRvJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYW4gT3BlblBHUCBtZXNzYWdlLlxuICogQ2FuIGJlIGFuIGVuY3J5cHRlZCBtZXNzYWdlLCBzaWduZWQgbWVzc2FnZSwgY29tcHJlc3NlZCBtZXNzYWdlIG9yIGxpdGVyYWwgbWVzc2FnZVxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fSBwYWNrZXRsaXN0IFRoZSBwYWNrZXRzIHRoYXQgZm9ybSB0aGlzIG1lc3NhZ2VcbiAqIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tMTEuM1xuICovXG5cbmZ1bmN0aW9uIE1lc3NhZ2UocGFja2V0bGlzdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWVzc2FnZSkpIHtcbiAgICByZXR1cm4gbmV3IE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIH1cbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRvIHdoaWNoIHRoZSBzZXNzaW9uIGtleSBpcyBlbmNyeXB0ZWRcbiAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTp0eXBlL2tleWlkPn0gYXJyYXkgb2Yga2V5aWQgb2JqZWN0c1xuICovXG5NZXNzYWdlLnByb3RvdHlwZS5nZXRFbmNyeXB0aW9uS2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIHBrRVNLZXlQYWNrZXRsaXN0ID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSk7XG4gIHBrRVNLZXlQYWNrZXRsaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAga2V5SWRzLnB1c2gocGFja2V0LnB1YmxpY0tleUlkKTtcbiAgfSk7XG4gIHJldHVybiBrZXlJZHM7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGtleSBJRHMgb2YgdGhlIGtleXMgdGhhdCBzaWduZWQgdGhlIG1lc3NhZ2VcbiAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTp0eXBlL2tleWlkPn0gYXJyYXkgb2Yga2V5aWQgb2JqZWN0c1xuICovXG5NZXNzYWdlLnByb3RvdHlwZS5nZXRTaWduaW5nS2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIG1zZyA9IHRoaXMudW53cmFwQ29tcHJlc3NlZCgpO1xuICAvLyBzZWFyY2ggZm9yIG9uZSBwYXNzIHNpZ25hdHVyZXNcbiAgdmFyIG9uZVBhc3NTaWdMaXN0ID0gbXNnLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0Lm9uZV9wYXNzX3NpZ25hdHVyZSk7XG4gIG9uZVBhc3NTaWdMaXN0LmZvckVhY2goZnVuY3Rpb24ocGFja2V0KSB7XG4gICAga2V5SWRzLnB1c2gocGFja2V0LnNpZ25pbmdLZXlJZCk7XG4gIH0pO1xuICAvLyBpZiBub3RoaW5nIGZvdW5kIGxvb2sgZm9yIHNpZ25hdHVyZSBwYWNrZXRzXG4gIGlmICgha2V5SWRzLmxlbmd0aCkge1xuICAgIHZhciBzaWduYXR1cmVMaXN0ID0gbXNnLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNpZ25hdHVyZSk7XG4gICAgc2lnbmF0dXJlTGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgICAga2V5SWRzLnB1c2gocGFja2V0Lmlzc3VlcktleUlkKTtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4ga2V5SWRzO1xufTtcblxuLyoqXG4gKiBEZWNyeXB0IHRoZSBtZXNzYWdlXG4gKiBAcGFyYW0ge21vZHVsZTprZXl+S2V5fSBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBkYXRhICAgICAgICAgICBcbiAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTptZXNzYWdlfk1lc3NhZ2U+fSBuZXcgbWVzc2FnZSB3aXRoIGRlY3J5cHRlZCBjb250ZW50XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihwcml2YXRlS2V5KSB7XG4gIHZhciBlbmNyeXB0aW9uS2V5SWRzID0gdGhpcy5nZXRFbmNyeXB0aW9uS2V5SWRzKCk7XG4gIGlmICghZW5jcnlwdGlvbktleUlkcy5sZW5ndGgpIHtcbiAgICAvLyBub3RoaW5nIHRvIGRlY3J5cHQgcmV0dXJuIHVubW9kaWZpZWQgbWVzc2FnZVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHZhciBwcml2YXRlS2V5UGFja2V0ID0gcHJpdmF0ZUtleS5nZXRQcml2YXRlS2V5UGFja2V0KGVuY3J5cHRpb25LZXlJZHMpO1xuICBpZiAoIXByaXZhdGVLZXlQYWNrZXQuaXNEZWNyeXB0ZWQpIHRocm93IG5ldyBFcnJvcignUHJpdmF0ZSBrZXkgaXMgbm90IGRlY3J5cHRlZC4nKTtcbiAgdmFyIHBrRVNLZXlQYWNrZXRsaXN0ID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSk7XG4gIHZhciBwa0VTS2V5UGFja2V0O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBrRVNLZXlQYWNrZXRsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHBrRVNLZXlQYWNrZXRsaXN0W2ldLnB1YmxpY0tleUlkLmVxdWFscyhwcml2YXRlS2V5UGFja2V0LmdldEtleUlkKCkpKSB7XG4gICAgICBwa0VTS2V5UGFja2V0ID0gcGtFU0tleVBhY2tldGxpc3RbaV07XG4gICAgICBwa0VTS2V5UGFja2V0LmRlY3J5cHQocHJpdmF0ZUtleVBhY2tldCk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKHBrRVNLZXlQYWNrZXQpIHtcbiAgICB2YXIgc3ltRW5jcnlwdGVkUGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQsIGVudW1zLnBhY2tldC5zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQpO1xuICAgIGlmIChzeW1FbmNyeXB0ZWRQYWNrZXRsaXN0Lmxlbmd0aCAhPT0gMCkge1xuICAgICAgdmFyIHN5bUVuY3J5cHRlZFBhY2tldCA9IHN5bUVuY3J5cHRlZFBhY2tldGxpc3RbMF07XG4gICAgICBzeW1FbmNyeXB0ZWRQYWNrZXQuZGVjcnlwdChwa0VTS2V5UGFja2V0LnNlc3Npb25LZXlBbGdvcml0aG0sIHBrRVNLZXlQYWNrZXQuc2Vzc2lvbktleSk7XG4gICAgICByZXR1cm4gbmV3IE1lc3NhZ2Uoc3ltRW5jcnlwdGVkUGFja2V0LnBhY2tldHMpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBHZXQgbGl0ZXJhbCBkYXRhIHRoYXQgaXMgdGhlIGJvZHkgb2YgdGhlIG1lc3NhZ2VcbiAqIEByZXR1cm4geyhTdHJpbmd8bnVsbCl9IGxpdGVyYWwgYm9keSBvZiB0aGUgbWVzc2FnZSBhcyBzdHJpbmdcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuZ2V0TGl0ZXJhbERhdGEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpdGVyYWwgPSB0aGlzLnBhY2tldHMuZmluZFBhY2tldChlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIHJldHVybiBsaXRlcmFsICYmIGxpdGVyYWwuZGF0YSB8fCBudWxsO1xufTtcblxuLyoqXG4gKiBHZXQgbGl0ZXJhbCBkYXRhIGFzIHRleHRcbiAqIEByZXR1cm4geyhTdHJpbmd8bnVsbCl9IGxpdGVyYWwgYm9keSBvZiB0aGUgbWVzc2FnZSBpbnRlcnByZXRlZCBhcyB0ZXh0XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpdGVyYWwgPSB0aGlzLnBhY2tldHMuZmluZFBhY2tldChlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIGlmIChsaXRlcmFsKSB7XG4gICAgcmV0dXJuIGxpdGVyYWwuZ2V0VGV4dCgpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEBwYXJhbSAge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0ga2V5cyBhcnJheSBvZiBrZXlzLCB1c2VkIHRvIGVuY3J5cHQgdGhlIG1lc3NhZ2VcbiAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTptZXNzYWdlfk1lc3NhZ2U+fSBuZXcgbWVzc2FnZSB3aXRoIGVuY3J5cHRlZCBjb250ZW50XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihrZXlzKSB7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgdmFyIHNlc3Npb25LZXkgPSBjcnlwdG8uZ2VuZXJhdGVTZXNzaW9uS2V5KGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBjb25maWcuZW5jcnlwdGlvbl9jaXBoZXIpKTtcbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBlbmNyeXB0aW9uS2V5UGFja2V0ID0ga2V5LmdldEVuY3J5cHRpb25LZXlQYWNrZXQoKTtcbiAgICBpZiAoZW5jcnlwdGlvbktleVBhY2tldCkge1xuICAgICAgdmFyIHBrRVNLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCk7XG4gICAgICBwa0VTS2V5UGFja2V0LnB1YmxpY0tleUlkID0gZW5jcnlwdGlvbktleVBhY2tldC5nZXRLZXlJZCgpO1xuICAgICAgcGtFU0tleVBhY2tldC5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbmNyeXB0aW9uS2V5UGFja2V0LmFsZ29yaXRobTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuc2Vzc2lvbktleSA9IHNlc3Npb25LZXk7XG4gICAgICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBhbGdvIGZyb20gc2lnbmF0dXJlXG4gICAgICBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyKTtcbiAgICAgIHBrRVNLZXlQYWNrZXQuZW5jcnlwdChlbmNyeXB0aW9uS2V5UGFja2V0KTtcbiAgICAgIHBhY2tldGxpc3QucHVzaChwa0VTS2V5UGFja2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCB2YWxpZCBrZXkgcGFja2V0IGZvciBlbmNyeXB0aW9uIGluIGtleSAnICsga2V5LnByaW1hcnlLZXkuZ2V0S2V5SWQoKS50b0hleCgpKTtcbiAgICB9XG4gIH0pO1xuICB2YXIgc3ltRW5jcnlwdGVkUGFja2V0O1xuICBpZiAoY29uZmlnLmludGVncml0eV9wcm90ZWN0KSB7XG4gICAgc3ltRW5jcnlwdGVkUGFja2V0ID0gbmV3IHBhY2tldC5zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQoKTtcbiAgfSBlbHNlIHtcbiAgICBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBuZXcgcGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkKCk7XG4gIH1cbiAgc3ltRW5jcnlwdGVkUGFja2V0LnBhY2tldHMgPSB0aGlzLnBhY2tldHM7XG4gIC8vVE9ETyBnZXQgcHJlZmVycmVkIGFsZ28gZnJvbSBzaWduYXR1cmVcbiAgc3ltRW5jcnlwdGVkUGFja2V0LmVuY3J5cHQoZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciksIHNlc3Npb25LZXkpO1xuICBwYWNrZXRsaXN0LnB1c2goc3ltRW5jcnlwdGVkUGFja2V0KTtcbiAgcmV0dXJuIG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xufTtcblxuLyoqXG4gKiBTaWduIHRoZSBtZXNzYWdlICh0aGUgbGl0ZXJhbCBkYXRhIHBhY2tldCBvZiB0aGUgbWVzc2FnZSlcbiAqIEBwYXJhbSAge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gcHJpdmF0ZUtleSBwcml2YXRlIGtleXMgd2l0aCBkZWNyeXB0ZWQgc2VjcmV0IGtleSBkYXRhIGZvciBzaWduaW5nXG4gKiBAcmV0dXJuIHttb2R1bGU6bWVzc2FnZX5NZXNzYWdlfSAgICAgIG5ldyBtZXNzYWdlIHdpdGggc2lnbmVkIGNvbnRlbnRcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uKHByaXZhdGVLZXlzKSB7XG5cbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcblxuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSB0aGlzLnBhY2tldHMuZmluZFBhY2tldChlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIGlmICghbGl0ZXJhbERhdGFQYWNrZXQpIHRocm93IG5ldyBFcnJvcignTm8gbGl0ZXJhbCBkYXRhIHBhY2tldCB0byBzaWduLicpO1xuICBcbiAgdmFyIGxpdGVyYWxGb3JtYXQgPSBlbnVtcy53cml0ZShlbnVtcy5saXRlcmFsLCBsaXRlcmFsRGF0YVBhY2tldC5mb3JtYXQpO1xuICB2YXIgc2lnbmF0dXJlVHlwZSA9IGxpdGVyYWxGb3JtYXQgPT0gZW51bXMubGl0ZXJhbC5iaW5hcnkgXG4gICAgICAgICAgICAgICAgICAgICAgPyBlbnVtcy5zaWduYXR1cmUuYmluYXJ5IDogZW51bXMuc2lnbmF0dXJlLnRleHQ7IFxuICBcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcml2YXRlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBvbmVQYXNzU2lnID0gbmV3IHBhY2tldC5vbmVfcGFzc19zaWduYXR1cmUoKTtcbiAgICBvbmVQYXNzU2lnLnR5cGUgPSBzaWduYXR1cmVUeXBlO1xuICAgIC8vVE9ETyBnZXQgcHJlZmVycmVkIGhhc2hnIGFsZ28gZnJvbSBrZXkgc2lnbmF0dXJlXG4gICAgb25lUGFzc1NpZy5oYXNoQWxnb3JpdGhtID0gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbiAgICB2YXIgc2lnbmluZ0tleVBhY2tldCA9IHByaXZhdGVLZXlzW2ldLmdldFNpZ25pbmdLZXlQYWNrZXQoKTtcbiAgICBpZiAoIXNpZ25pbmdLZXlQYWNrZXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgdmFsaWQga2V5IHBhY2tldCBmb3Igc2lnbmluZyBpbiBrZXkgJyArIHByaXZhdGVLZXlzW2ldLnByaW1hcnlLZXkuZ2V0S2V5SWQoKS50b0hleCgpKTtcbiAgICB9XG4gICAgb25lUGFzc1NpZy5wdWJsaWNLZXlBbGdvcml0aG0gPSBzaWduaW5nS2V5UGFja2V0LmFsZ29yaXRobTtcbiAgICBvbmVQYXNzU2lnLnNpZ25pbmdLZXlJZCA9IHNpZ25pbmdLZXlQYWNrZXQuZ2V0S2V5SWQoKTtcbiAgICBwYWNrZXRsaXN0LnB1c2gob25lUGFzc1NpZyk7XG4gIH1cblxuICBwYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICBcbiAgZm9yICh2YXIgaSA9IHByaXZhdGVLZXlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIHNpZ25hdHVyZVBhY2tldCA9IG5ldyBwYWNrZXQuc2lnbmF0dXJlKCk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnNpZ25hdHVyZVR5cGUgPSBzaWduYXR1cmVUeXBlO1xuICAgIHNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbiAgICBzaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgaWYgKCFzaWduaW5nS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnNpZ24oc2lnbmluZ0tleVBhY2tldCwgbGl0ZXJhbERhdGFQYWNrZXQpO1xuICAgIHBhY2tldGxpc3QucHVzaChzaWduYXR1cmVQYWNrZXQpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgbWVzc2FnZSBzaWduYXR1cmVzXG4gKiBAcGFyYW0ge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybiB7QXJyYXk8KHtrZXlpZDogbW9kdWxlOnR5cGUva2V5aWQsIHZhbGlkOiBCb29sZWFufSk+fSBsaXN0IG9mIHNpZ25lcidzIGtleWlkIGFuZCB2YWxpZGl0eSBvZiBzaWduYXR1cmVcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHVibGljS2V5cykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBtc2cgPSB0aGlzLnVud3JhcENvbXByZXNzZWQoKTtcbiAgdmFyIGxpdGVyYWxEYXRhTGlzdCA9IG1zZy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5saXRlcmFsKTtcbiAgaWYgKGxpdGVyYWxEYXRhTGlzdC5sZW5ndGggIT09IDEpIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgdmVyaWZ5IG1lc3NhZ2Ugd2l0aCBvbmUgbGl0ZXJhbCBkYXRhIHBhY2tldC4nKTtcbiAgdmFyIHNpZ25hdHVyZUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgcHVibGljS2V5cy5mb3JFYWNoKGZ1bmN0aW9uKHB1YktleSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnbmF0dXJlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHB1YmxpY0tleVBhY2tldCA9IHB1YktleS5nZXRQdWJsaWNLZXlQYWNrZXQoW3NpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWRdKTtcbiAgICAgIGlmIChwdWJsaWNLZXlQYWNrZXQpIHtcbiAgICAgICAgdmFyIHZlcmlmaWVkU2lnID0ge307XG4gICAgICAgIHZlcmlmaWVkU2lnLmtleWlkID0gc2lnbmF0dXJlTGlzdFtpXS5pc3N1ZXJLZXlJZDtcbiAgICAgICAgdmVyaWZpZWRTaWcudmFsaWQgPSBzaWduYXR1cmVMaXN0W2ldLnZlcmlmeShwdWJsaWNLZXlQYWNrZXQsIGxpdGVyYWxEYXRhTGlzdFswXSk7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZlcmlmaWVkU2lnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogVW53cmFwIGNvbXByZXNzZWQgbWVzc2FnZVxuICogQHJldHVybiB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gbWVzc2FnZSBDb250ZW50IG9mIGNvbXByZXNzZWQgbWVzc2FnZVxuICovXG5NZXNzYWdlLnByb3RvdHlwZS51bndyYXBDb21wcmVzc2VkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb21wcmVzc2VkID0gdGhpcy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5jb21wcmVzc2VkKTtcbiAgaWYgKGNvbXByZXNzZWQubGVuZ3RoKSB7XG4gICAgcmV0dXJuIG5ldyBNZXNzYWdlKGNvbXByZXNzZWRbMF0ucGFja2V0cyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0dXJucyBBU0NJSSBhcm1vcmVkIHRleHQgb2YgbWVzc2FnZVxuICogQHJldHVybiB7U3RyaW5nfSBBU0NJSSBhcm1vclxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5hcm1vciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gYXJtb3IuZW5jb2RlKGVudW1zLmFybW9yLm1lc3NhZ2UsIHRoaXMucGFja2V0cy53cml0ZSgpKTtcbn07XG5cbi8qKlxuICogcmVhZHMgYW4gT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2UgYW5kIHJldHVybnMgYSBtZXNzYWdlIG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWRUZXh0IHRleHQgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJuIHttb2R1bGU6bWVzc2FnZX5NZXNzYWdlfSBuZXcgbWVzc2FnZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgLy9UT0RPIGhvdyBkbyB3ZSB3YW50IHRvIGhhbmRsZSBiYWQgdGV4dD8gRXhjZXB0aW9uIHRocm93aW5nXG4gIC8vVE9ETyBkb24ndCBhY2NlcHQgbm9uLW1lc3NhZ2UgYXJtb3JlZCB0ZXh0c1xuICB2YXIgaW5wdXQgPSBhcm1vci5kZWNvZGUoYXJtb3JlZFRleHQpLmRhdGE7XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIHBhY2tldGxpc3QucmVhZChpbnB1dCk7XG4gIHZhciBuZXdNZXNzYWdlID0gbmV3IE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG4vKipcbiAqIGNyZWF0ZXMgbmV3IG1lc3NhZ2Ugb2JqZWN0IGZyb20gdGV4dFxuICogQHBhcmFtIHtTdHJpbmd9IHRleHRcbiAqIEByZXR1cm4ge21vZHVsZTptZXNzYWdlfk1lc3NhZ2V9IG5ldyBtZXNzYWdlIG9iamVjdFxuICovXG5mdW5jdGlvbiBmcm9tVGV4dCh0ZXh0KSB7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IG5ldyBwYWNrZXQubGl0ZXJhbCgpO1xuICAvLyB0ZXh0IHdpbGwgYmUgY29udmVydGVkIHRvIFVURjhcbiAgbGl0ZXJhbERhdGFQYWNrZXQuc2V0VGV4dCh0ZXh0KTtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBsaXRlcmFsRGF0YVBhY2tldGxpc3QucHVzaChsaXRlcmFsRGF0YVBhY2tldCk7XG4gIHZhciBuZXdNZXNzYWdlID0gbmV3IE1lc3NhZ2UobGl0ZXJhbERhdGFQYWNrZXRsaXN0KTtcbiAgcmV0dXJuIG5ld01lc3NhZ2U7XG59XG5cbi8qKlxuICogY3JlYXRlcyBuZXcgbWVzc2FnZSBvYmplY3QgZnJvbSBiaW5hcnkgZGF0YVxuICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzXG4gKiBAcmV0dXJuIHttb2R1bGU6bWVzc2FnZX5NZXNzYWdlfSBuZXcgbWVzc2FnZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gZnJvbUJpbmFyeShieXRlcykge1xuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXQuc2V0Qnl0ZXMoYnl0ZXMsIGVudW1zLnJlYWQoZW51bXMubGl0ZXJhbCwgZW51bXMubGl0ZXJhbC5iaW5hcnkpKTtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBsaXRlcmFsRGF0YVBhY2tldGxpc3QucHVzaChsaXRlcmFsRGF0YVBhY2tldCk7XG4gIHZhciBuZXdNZXNzYWdlID0gbmV3IE1lc3NhZ2UobGl0ZXJhbERhdGFQYWNrZXRsaXN0KTtcbiAgcmV0dXJuIG5ld01lc3NhZ2U7XG59XG5cbmV4cG9ydHMuTWVzc2FnZSA9IE1lc3NhZ2U7XG5leHBvcnRzLnJlYWRBcm1vcmVkID0gcmVhZEFybW9yZWQ7XG5leHBvcnRzLmZyb21UZXh0ID0gZnJvbVRleHQ7XG5leHBvcnRzLmZyb21CaW5hcnkgPSBmcm9tQmluYXJ5O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBvcGVucGdwIGJhc2UgbW9kdWxlIHNob3VsZCBwcm92aWRlIGFsbCBvZiB0aGUgZnVuY3Rpb25hbGl0eSBcbiAqIHRvIGNvbnN1bWUgdGhlIG9wZW5wZ3AuanMgbGlicmFyeS4gQWxsIGFkZGl0aW9uYWwgY2xhc3NlcyBhcmUgZG9jdW1lbnRlZCBcbiAqIGZvciBleHRlbmRpbmcgYW5kIGRldmVsb3Bpbmcgb24gdG9wIG9mIHRoZSBiYXNlIGxpYnJhcnkuXG4gKi9cblxuLyoqIEBtb2R1bGUgb3BlbnBncCAqL1xuXG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpO1xudmFyIG1lc3NhZ2UgPSByZXF1aXJlKCcuL21lc3NhZ2UuanMnKTtcbnZhciBjbGVhcnRleHQgPSByZXF1aXJlKCcuL2NsZWFydGV4dC5qcycpO1xudmFyIGtleSA9IHJlcXVpcmUoJy4va2V5LmpzJyk7XG5cblxuLyoqXG4gKiBFbmNyeXB0cyBtZXNzYWdlIHRleHQgd2l0aCBrZXlzXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHBhcmFtICB7U3RyaW5nfSB0ZXh0IG1lc3NhZ2UgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgZW5jcnlwdGVkIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBlbmNyeXB0TWVzc2FnZShrZXlzLCB0ZXh0KSB7XG4gIHZhciBtc2cgPSBtZXNzYWdlLmZyb21UZXh0KHRleHQpO1xuICBtc2cgPSBtc2cuZW5jcnlwdChrZXlzKTtcbiAgdmFyIGFybW9yZWQgPSBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3IubWVzc2FnZSwgbXNnLnBhY2tldHMud3JpdGUoKSk7XG4gIHJldHVybiBhcm1vcmVkO1xufVxuXG4vKipcbiAqIFNpZ25zIG1lc3NhZ2UgdGV4dCBhbmQgZW5jcnlwdHMgaXRcbiAqIEBwYXJhbSAge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gIHB1YmxpY0tleXMgYXJyYXkgb2Yga2V5cywgdXNlZCB0byBlbmNyeXB0IHRoZSBtZXNzYWdlXG4gKiBAcGFyYW0gIHttb2R1bGU6a2V5fktleX0gICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICBtZXNzYWdlIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSAgICAgICAgICAgIGVuY3J5cHRlZCBBU0NJSSBhcm1vcmVkIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gc2lnbkFuZEVuY3J5cHRNZXNzYWdlKHB1YmxpY0tleXMsIHByaXZhdGVLZXksIHRleHQpIHtcbiAgdmFyIG1zZyA9IG1lc3NhZ2UuZnJvbVRleHQodGV4dCk7XG4gIG1zZyA9IG1zZy5zaWduKFtwcml2YXRlS2V5XSk7XG4gIG1zZyA9IG1zZy5lbmNyeXB0KHB1YmxpY0tleXMpO1xuICB2YXIgYXJtb3JlZCA9IGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCBtc2cucGFja2V0cy53cml0ZSgpKTtcbiAgcmV0dXJuIGFybW9yZWQ7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZVxuICogQHBhcmFtICB7bW9kdWxlOmtleX5LZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gbWVzc2FnZSAgICB0aGUgbWVzc2FnZSBvYmplY3Qgd2l0aCB0aGUgZW5jcnlwdGVkIGRhdGFcbiAqIEByZXR1cm4geyhTdHJpbmd8bnVsbCl9ICAgICAgICBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgbnVsbCBpZiBubyBsaXRlcmFsIGRhdGEgZm91bmRcbiAqL1xuZnVuY3Rpb24gZGVjcnlwdE1lc3NhZ2UocHJpdmF0ZUtleSwgbWVzc2FnZSkge1xuICBtZXNzYWdlID0gbWVzc2FnZS5kZWNyeXB0KHByaXZhdGVLZXkpO1xuICByZXR1cm4gbWVzc2FnZS5nZXRUZXh0KCk7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZSBhbmQgdmVyaWZpZXMgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bW9kdWxlOmtleX5LZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSAgIHB1YmxpY0tleXMgcHVibGljIGtleXMgdG8gdmVyaWZ5IHNpZ25hdHVyZXNcbiAqIEBwYXJhbSAge21vZHVsZTptZXNzYWdlfk1lc3NhZ2V9IG1lc3NhZ2UgICAgdGhlIG1lc3NhZ2Ugb2JqZWN0IHdpdGggc2lnbmVkIGFuZCBlbmNyeXB0ZWQgZGF0YVxuICogQHJldHVybiB7e3RleHQ6IFN0cmluZywgc2lnbmF0dXJlczogQXJyYXk8e2tleWlkOiBtb2R1bGU6dHlwZS9rZXlpZCwgdmFsaWQ6IEJvb2xlYW59Pn19XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZCBtZXNzYWdlIGFzIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHZlcmlmaWVkIHNpZ25hdHVyZXMgb3IgbnVsbCBpZiBubyBsaXRlcmFsIGRhdGEgZm91bmRcbiAqL1xuZnVuY3Rpb24gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2UocHJpdmF0ZUtleSwgcHVibGljS2V5cywgbWVzc2FnZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIG1lc3NhZ2UgPSBtZXNzYWdlLmRlY3J5cHQocHJpdmF0ZUtleSk7XG4gIHJlc3VsdC50ZXh0ID0gbWVzc2FnZS5nZXRUZXh0KCk7XG4gIGlmIChyZXN1bHQudGV4dCkge1xuICAgIHJlc3VsdC5zaWduYXR1cmVzID0gbWVzc2FnZS52ZXJpZnkocHVibGljS2V5cyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBTaWducyBhIGNsZWFydGV4dCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICBwcml2YXRlS2V5cyBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgdG8gc2lnbiBjbGVhcnRleHRcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICAgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgICAgICAgIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBzaWduQ2xlYXJNZXNzYWdlKHByaXZhdGVLZXlzLCB0ZXh0KSB7XG4gIHZhciBjbGVhcnRleHRNZXNzYWdlID0gbmV3IGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKHRleHQpO1xuICBjbGVhcnRleHRNZXNzYWdlLnNpZ24ocHJpdmF0ZUtleXMpO1xuICByZXR1cm4gY2xlYXJ0ZXh0TWVzc2FnZS5hcm1vcigpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIHNpZ25hdHVyZXMgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICAgICAgICAgICAgcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bW9kdWxlOmNsZWFydGV4dH5DbGVhcnRleHRNZXNzYWdlfSBtZXNzYWdlICAgIGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdCB3aXRoIHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge3t0ZXh0OiBTdHJpbmcsIHNpZ25hdHVyZXM6IEFycmF5PHtrZXlpZDogbW9kdWxlOnR5cGUva2V5aWQsIHZhbGlkOiBCb29sZWFufT59fVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhcnRleHQgd2l0aCBzdGF0dXMgb2YgdmVyaWZpZWQgc2lnbmF0dXJlc1xuICovXG5mdW5jdGlvbiB2ZXJpZnlDbGVhclNpZ25lZE1lc3NhZ2UocHVibGljS2V5cywgbWVzc2FnZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGlmICghKG1lc3NhZ2UgaW5zdGFuY2VvZiBjbGVhcnRleHQuQ2xlYXJ0ZXh0TWVzc2FnZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciBbbWVzc2FnZV0gbmVlZHMgdG8gYmUgb2YgdHlwZSBDbGVhcnRleHRNZXNzYWdlLicpO1xuICB9XG4gIHJlc3VsdC50ZXh0ID0gbWVzc2FnZS5nZXRUZXh0KCk7XG4gIHJlc3VsdC5zaWduYXR1cmVzID0gbWVzc2FnZS52ZXJpZnkocHVibGljS2V5cyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgbmV3IE9wZW5QR1Aga2V5IHBhaXIuIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIFJTQSBrZXlzLlxuICogUHJpbWFyeSBhbmQgc3Via2V5IHdpbGwgYmUgb2Ygc2FtZSB0eXBlLlxuICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlICAgIHRvIGluZGljYXRlIHdoYXQgdHlwZSBvZiBrZXkgdG8gbWFrZS4gXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBIGlzIDEuIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tOS4xXG4gKiBAcGFyYW0ge0ludGVnZXJ9IG51bUJpdHMgICAgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBrZXkgY3JlYXRpb24uIChzaG91bGQgYmUgMTAyNCssIGdlbmVyYWxseSlcbiAqIEBwYXJhbSB7U3RyaW5nfSAgdXNlcklkICAgICBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiBcIlVzZXIgTmFtZSA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gKiBAcGFyYW0ge1N0cmluZ30gIHBhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBlbmNyeXB0IHRoZSByZXN1bHRpbmcgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge09iamVjdH0ge2tleTogQXJyYXk8bW9kdWxlOmtleX5LZXk+LCBwcml2YXRlS2V5QXJtb3JlZDogQXJyYXk8U3RyaW5nPiwgcHVibGljS2V5QXJtb3JlZDogQXJyYXk8U3RyaW5nPn1cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBuZXdLZXkgPSBrZXkuZ2VuZXJhdGUoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKTtcbiAgcmVzdWx0LmtleSA9IG5ld0tleTtcbiAgcmVzdWx0LnByaXZhdGVLZXlBcm1vcmVkID0gbmV3S2V5LmFybW9yKCk7XG4gIHJlc3VsdC5wdWJsaWNLZXlBcm1vcmVkID0gbmV3S2V5LnRvUHVibGljKCkuYXJtb3IoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5lbmNyeXB0TWVzc2FnZSA9IGVuY3J5cHRNZXNzYWdlO1xuZXhwb3J0cy5zaWduQW5kRW5jcnlwdE1lc3NhZ2UgPSBzaWduQW5kRW5jcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRNZXNzYWdlID0gZGVjcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlID0gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2VcbmV4cG9ydHMuc2lnbkNsZWFyTWVzc2FnZSA9IHNpZ25DbGVhck1lc3NhZ2U7XG5leHBvcnRzLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZSA9IHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZTtcbmV4cG9ydHMuZ2VuZXJhdGVLZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyO1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLy8gVGhpcyBpcyBwcmV0dHkgdWdseSwgYnV0IGJyb3dzZXJpZnkgbmVlZHMgdG8gaGF2ZSB0aGUgcmVxdWlyZXMgZXhwbGljaXRseSB3cml0dGVuLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbXByZXNzZWQ6IHJlcXVpcmUoJy4vY29tcHJlc3NlZC5qcycpLFxuICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkLmpzJyksXG4gIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzJyksXG4gIHN5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXk6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcycpLFxuICBsaXRlcmFsOiByZXF1aXJlKCcuL2xpdGVyYWwuanMnKSxcbiAgcHVibGljX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiByZXF1aXJlKCcuL3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzJyksXG4gIG1hcmtlcjogcmVxdWlyZSgnLi9tYXJrZXIuanMnKSxcbiAgcHVibGljX3N1YmtleTogcmVxdWlyZSgnLi9wdWJsaWNfc3Via2V5LmpzJyksXG4gIHVzZXJfYXR0cmlidXRlOiByZXF1aXJlKCcuL3VzZXJfYXR0cmlidXRlLmpzJyksXG4gIG9uZV9wYXNzX3NpZ25hdHVyZTogcmVxdWlyZSgnLi9vbmVfcGFzc19zaWduYXR1cmUuanMnKSxcbiAgc2VjcmV0X2tleTogcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyksXG4gIHVzZXJpZDogcmVxdWlyZSgnLi91c2VyaWQuanMnKSxcbiAgc2VjcmV0X3N1YmtleTogcmVxdWlyZSgnLi9zZWNyZXRfc3Via2V5LmpzJyksXG4gIHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcbiAgdHJ1c3Q6IHJlcXVpcmUoJy4vdHJ1c3QuanMnKVxufVxuXG5mb3IgKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuICB2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuICBpZiAocGFja2V0Q2xhc3MgIT0gdW5kZWZpbmVkKVxuICAgIHBhY2tldENsYXNzLnByb3RvdHlwZS50YWcgPSBlbnVtcy5wYWNrZXRbaV07XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvY29tcHJlc3NlZCAqL1xuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBKWEcgPSByZXF1aXJlKCcuLi9jb21wcmVzc2lvbi9qeGcuanMnKSxcbiAgYmFzZTY0ID0gcmVxdWlyZSgnLi4vZW5jb2RpbmcvYmFzZTY0LmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBDb21wcmVzc2VkIERhdGEgUGFja2V0IChUYWcgOClcbiAqIFxuICogUkZDNDg4MCA1LjY6XG4gKiBUaGUgQ29tcHJlc3NlZCBEYXRhIHBhY2tldCBjb250YWlucyBjb21wcmVzc2VkIGRhdGEuICBUeXBpY2FsbHksIHRoaXNcbiAqIHBhY2tldCBpcyBmb3VuZCBhcyB0aGUgY29udGVudHMgb2YgYW4gZW5jcnlwdGVkIHBhY2tldCwgb3IgZm9sbG93aW5nXG4gKiBhIFNpZ25hdHVyZSBvciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0LCBhbmQgY29udGFpbnMgYSBsaXRlcmFsIGRhdGFcbiAqIHBhY2tldC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfY29tcHJlc3NlZCgpIHtcbiAgLyoqIEB0eXBlIHttb2R1bGU6cGFja2V0L3BhY2tldGxpc3R9ICovXG4gIHRoaXMucGFja2V0cztcbiAgLyoqIEB0eXBlIHtjb21wcmVzc2lvbn0gKi9cbiAgdGhpcy5hbGdvcml0aG0gPSAndW5jb21wcmVzc2VkJztcblxuICB0aGlzLmNvbXByZXNzZWQgPSBudWxsO1xuXG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIHRoZSBwYWNrZXQuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDggcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgXG4gICAqIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvY29tcHJlc3NlZH0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIE9uZSBvY3RldCB0aGF0IGdpdmVzIHRoZSBhbGdvcml0aG0gdXNlZCB0byBjb21wcmVzcyB0aGUgcGFja2V0LlxuICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5jb21wcmVzc2lvbiwgYnl0ZXMuY2hhckNvZGVBdCgwKSk7XG5cbiAgICAvLyBDb21wcmVzc2VkIGRhdGEsIHdoaWNoIG1ha2VzIHVwIHRoZSByZW1haW5kZXIgb2YgdGhlIHBhY2tldC5cbiAgICB0aGlzLmNvbXByZXNzZWQgPSBieXRlcy5zdWJzdHIoMSk7XG5cbiAgICB0aGlzLmRlY29tcHJlc3MoKTtcbiAgfVxuXG5cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY29tcHJlc3NlZCA9PSBudWxsKVxuICAgICAgdGhpcy5jb21wcmVzcygpO1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuY29tcHJlc3Npb24sIHRoaXMuYWxnb3JpdGhtKSkgKyB0aGlzLmNvbXByZXNzZWQ7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBEZWNvbXByZXNzaW9uIG1ldGhvZCBmb3IgZGVjb21wcmVzc2luZyB0aGUgY29tcHJlc3NlZCBkYXRhXG4gICAqIHJlYWQgYnkgcmVhZF9wYWNrZXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgZGVjb21wcmVzc2VkIGRhdGFcbiAgICovXG4gIHRoaXMuZGVjb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBkZWNvbXByZXNzZWQ7XG5cbiAgICBzd2l0Y2ggKHRoaXMuYWxnb3JpdGhtKSB7XG4gICAgICBjYXNlICd1bmNvbXByZXNzZWQnOlxuICAgICAgICBkZWNvbXByZXNzZWQgPSB0aGlzLmNvbXByZXNzZWQ7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6aXAnOlxuICAgICAgICB2YXIgY29tcERhdGEgPSB0aGlzLmNvbXByZXNzZWQ7XG5cbiAgICAgICAgdmFyIHJhZGl4ID0gYmFzZTY0LmVuY29kZShjb21wRGF0YSkucmVwbGFjZSgvXFxuL2csIFwiXCIpO1xuICAgICAgICAvLyBubyBoZWFkZXIgaW4gdGhpcyBjYXNlLCBkaXJlY3RseSBjYWxsIGRlZmxhdGVcbiAgICAgICAgdmFyIGp4Z19vYmogPSBuZXcgSlhHLlV0aWwuVW56aXAoSlhHLlV0aWwuQmFzZTY0LmRlY29kZUFzQXJyYXkocmFkaXgpKTtcblxuICAgICAgICBkZWNvbXByZXNzZWQgPSB1bmVzY2FwZShqeGdfb2JqLmRlZmxhdGUoKVswXVswXSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgLy9SRkMgMTk1MC4gQml0cyAwLTMgQ29tcHJlc3Npb24gTWV0aG9kXG4gICAgICAgIHZhciBjb21wcmVzc2lvbk1ldGhvZCA9IHRoaXMuY29tcHJlc3NlZC5jaGFyQ29kZUF0KDApICUgMHgxMDtcblxuICAgICAgICAvL0JpdHMgNC03IFJGQyAxOTUwIGFyZSBMWjc3IFdpbmRvdy4gR2VuZXJhbGx5IHRoaXMgdmFsdWUgaXMgNyA9PSAzMmsgd2luZG93IHNpemUuXG4gICAgICAgIC8vIDJuZCBCeXRlIGluIFJGQyAxOTUwIGlzIGZvciBcIkZMQUdzXCIgQWxsb3dzIGZvciBhIERpY3Rpb25hcnkgXG4gICAgICAgIC8vIChob3cgaXMgdGhpcyBkZWZpbmVkKS4gQmFzaWMgY2hlY2tzdW0sIGFuZCBjb21wcmVzc2lvbiBsZXZlbC5cblxuICAgICAgICBpZiAoY29tcHJlc3Npb25NZXRob2QgPT0gOCkgeyAvL0NNIDggaXMgZm9yIERFRkxBVEUsIFJGQyAxOTUxXG4gICAgICAgICAgLy8gcmVtb3ZlIDQgYnl0ZXMgQURMRVIzMiBjaGVja3N1bSBmcm9tIHRoZSBlbmRcbiAgICAgICAgICB2YXIgY29tcERhdGEgPSB0aGlzLmNvbXByZXNzZWQuc3Vic3RyaW5nKDAsIHRoaXMuY29tcHJlc3NlZC5sZW5ndGggLSA0KTtcbiAgICAgICAgICB2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZywgXCJcIik7XG4gICAgICAgICAgLy9UT0RPIGNoZWNrIEFETEVSMzIgY2hlY2tzdW1cbiAgICAgICAgICBkZWNvbXByZXNzZWQgPSBKWEcuZGVjb21wcmVzcyhyYWRpeCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBvbmx5IHN1cHBvcnRzIFwiICtcbiAgICAgICAgICAgIFwiREVGTEFURSBjb21wcmVzc2lvbiBtZXRob2QuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdiemlwMic6XG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21wcmVzc2lvbiBhbGdvcml0aG0gQlppcDIgW0JaMl0gaXMgbm90IGltcGxlbWVudGVkLicpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy5hbG9ncml0aG0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNvbXByZXNzZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXByZXNzIHRoZSBwYWNrZXQgZGF0YSAobWVtYmVyIGRlY29tcHJlc3NlZERhdGEpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb21wcmVzc2VkIGRhdGEgc3RvcmVkIGluIGF0dHJpYnV0ZSBjb21wcmVzc2VkRGF0YVxuICAgKi9cbiAgdGhpcy5jb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblxuICAgICAgY2FzZSAndW5jb21wcmVzc2VkJzpcbiAgICAgICAgLy8gLSBVbmNvbXByZXNzZWRcbiAgICAgICAgdGhpcy5jb21wcmVzc2VkID0gdGhpcy5wYWNrZXRzLndyaXRlKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6aXAnOlxuICAgICAgICAvLyAtIFpJUCBbUkZDMTk1MV1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIFpJUCBbUkZDMTk1MV0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3psaWInOlxuICAgICAgICAvLyAtIFpMSUIgW1JGQzE5NTBdXG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIFpMSUIgW1JGQzE5NTBdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdiemlwMic6XG4gICAgICAgIC8vICAtIEJaaXAyIFtCWjJdXG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIEJaaXAyIFtCWjJdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gdW5rbm93biA6XCIgKyB0aGlzLnR5cGUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn07XG4iLCJ2YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbGlzdDogcmVxdWlyZSgnLi9wYWNrZXRsaXN0LmpzJyksXG59O1xuXG52YXIgcGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKTtcblxuZm9yICh2YXIgaSBpbiBwYWNrZXRzKVxuICBtb2R1bGUuZXhwb3J0c1tpXSA9IHBhY2tldHNbaV07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvbGl0ZXJhbCAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgTGl0ZXJhbCBEYXRhIFBhY2tldCAoVGFnIDExKVxuICogXG4gKiBSRkM0ODgwIDUuOTogQSBMaXRlcmFsIERhdGEgcGFja2V0IGNvbnRhaW5zIHRoZSBib2R5IG9mIGEgbWVzc2FnZTsgZGF0YSB0aGF0XG4gKiBpcyBub3QgdG8gYmUgZnVydGhlciBpbnRlcnByZXRlZC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfbGl0ZXJhbCgpIHtcbiAgdGhpcy5mb3JtYXQgPSAndXRmOCc7IC8vIGRlZmF1bHQgZm9ybWF0IGZvciBsaXRlcmFsIGRhdGEgcGFja2V0c1xuICB0aGlzLmRhdGEgPSAnJzsgLy8gbGl0ZXJhbCBkYXRhIHJlcHJlc2VudGF0aW9uIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZyBvciBieXRlc1xuICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSgpO1xuXG5cbiAgLyoqXG4gICAqIFNldCB0aGUgcGFja2V0IGRhdGEgdG8gYSBqYXZhc2NyaXB0IG5hdGl2ZSBzdHJpbmcsIGVuZCBvZiBsaW5lIFxuICAgKiB3aWxsIGJlIG5vcm1hbGl6ZWQgdG8gXFxyXFxuIGFuZCBieSBkZWZhdWx0IHRleHQgaXMgY29udmVydGVkIHRvIFVURjhcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgQW55IG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKi9cbiAgdGhpcy5zZXRUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuICAgIC8vIG5vcm1hbGl6ZSBFT0wgdG8gXFxyXFxuXG4gICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKS5yZXBsYWNlKC9cXG4vZywgJ1xcclxcbicpO1xuICAgIC8vIGVuY29kZSBVVEY4XG4gICAgdGhpcy5kYXRhID0gdGhpcy5mb3JtYXQgPT0gJ3V0ZjgnID8gdXRpbC5lbmNvZGVfdXRmOCh0ZXh0KSA6IHRleHQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBsaXRlcmFsIGRhdGEgcGFja2V0cyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAgICogd2l0aCBub3JtYWxpemVkIGVuZCBvZiBsaW5lIHRvIFxcblxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGxpdGVyYWwgZGF0YSBhcyB0ZXh0XG4gICAqL1xuICB0aGlzLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBkZWNvZGUgVVRGOFxuICAgIHZhciB0ZXh0ID0gdXRpbC5kZWNvZGVfdXRmOCh0aGlzLmRhdGEpO1xuICAgIC8vIG5vcm1hbGl6ZSBFT0wgdG8gXFxuXG4gICAgcmV0dXJuIHRleHQucmVwbGFjZSgvXFxyXFxuL2csICdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmcgb2YgYnl0ZXMuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBUaGUgc3RyaW5nIG9mIGJ5dGVzXG4gICAqIEBwYXJhbSB7dXRmOHxiaW5hcnl8dGV4dH0gZm9ybWF0IFRoZSBmb3JtYXQgb2YgdGhlIHN0cmluZyBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5zZXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzLCBmb3JtYXQpIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICB0aGlzLmRhdGEgPSBieXRlcztcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYnl0ZSBzZXF1ZW5jZSByZXByZXNlbnRpbmcgdGhlIGxpdGVyYWwgcGFja2V0IGRhdGFcbiAgICogQHJldHVybnMge1N0cmluZ30gQSBzZXF1ZW5jZSBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5nZXRCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGE7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L2xpdGVyYWx9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyAtIEEgb25lLW9jdGV0IGZpZWxkIHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgZGF0YSBpcyBmb3JtYXR0ZWQuXG5cbiAgICB2YXIgZm9ybWF0ID0gZW51bXMucmVhZChlbnVtcy5saXRlcmFsLCBieXRlcy5jaGFyQ29kZUF0KDApKTtcblxuICAgIHZhciBmaWxlbmFtZV9sZW4gPSBieXRlcy5jaGFyQ29kZUF0KDEpO1xuICAgIHRoaXMuZmlsZW5hbWUgPSB1dGlsLmRlY29kZV91dGY4KGJ5dGVzLnN1YnN0cigyLCBmaWxlbmFtZV9sZW4pKTtcblxuICAgIHRoaXMuZGF0ZSA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKDIgKyBmaWxlbmFtZV9sZW4sIDQpKTtcblxuICAgIHZhciBkYXRhID0gYnl0ZXMuc3Vic3RyaW5nKDYgKyBmaWxlbmFtZV9sZW4pO1xuXG4gICAgdGhpcy5zZXRCeXRlcyhkYXRhLCBmb3JtYXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgVGhlIGRhdGEgdG8gYmUgaW5zZXJ0ZWQgYXMgYm9keVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZy1yZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0XG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZpbGVuYW1lID0gdXRpbC5lbmNvZGVfdXRmOChcIm1zZy50eHRcIik7XG5cbiAgICB2YXIgZGF0YSA9IHRoaXMuZ2V0Qnl0ZXMoKTtcblxuICAgIHZhciByZXN1bHQgPSAnJztcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5saXRlcmFsLCB0aGlzLmZvcm1hdCkpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGZpbGVuYW1lLmxlbmd0aCk7XG4gICAgcmVzdWx0ICs9IGZpbGVuYW1lO1xuICAgIHJlc3VsdCArPSB1dGlsLndyaXRlRGF0ZSh0aGlzLmRhdGUpO1xuICAgIHJlc3VsdCArPSBkYXRhO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIHBhY2tldC9tYXJrZXIgKi9cblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIHN0cmFuZ2UgXCJNYXJrZXIgcGFja2V0XCIgKFRhZyAxMClcbiAqIFxuICogUkZDNDg4MCA1Ljg6IEFuIGV4cGVyaW1lbnRhbCB2ZXJzaW9uIG9mIFBHUCB1c2VkIHRoaXMgcGFja2V0IGFzIHRoZSBMaXRlcmFsXG4gKiBwYWNrZXQsIGJ1dCBubyByZWxlYXNlZCB2ZXJzaW9uIG9mIFBHUCBnZW5lcmF0ZWQgTGl0ZXJhbCBwYWNrZXRzIHdpdGggdGhpc1xuICogdGFnLiBXaXRoIFBHUCA1LngsIHRoaXMgcGFja2V0IGhhcyBiZWVuIHJlYXNzaWduZWQgYW5kIGlzIHJlc2VydmVkIGZvciB1c2UgYXNcbiAqIHRoZSBNYXJrZXIgcGFja2V0LlxuICogXG4gKiBTdWNoIGEgcGFja2V0IE1VU1QgYmUgaWdub3JlZCB3aGVuIHJlY2VpdmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgbGl0ZXJhbCBkYXRhIHBhY2tldCAodGFnIDEwKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEwIHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uXG4gICAqICAgICAgICAgICAgUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvbWFya2VyfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoMCkgPT0gMHg1MCAmJiAvLyBQXG4gICAgYnl0ZXMuY2hhckNvZGVBdCgxKSA9PSAweDQ3ICYmIC8vIEdcbiAgICBieXRlcy5jaGFyQ29kZUF0KDIpID09IDB4NTApIC8vIFBcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIC8vIG1hcmtlciBwYWNrZXQgZG9lcyBub3QgY29udGFpbiBcIlBHUFwiXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvb25lX3Bhc3Nfc2lnbmF0dXJlICovXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBPbmUtUGFzcyBTaWduYXR1cmUgUGFja2V0cyAoVGFnIDQpXG4gKiBcbiAqIFJGQzQ4ODAgNS40OlxuICogVGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgcHJlY2VkZXMgdGhlIHNpZ25lZCBkYXRhIGFuZCBjb250YWluc1xuICogZW5vdWdoIGluZm9ybWF0aW9uIHRvIGFsbG93IHRoZSByZWNlaXZlciB0byBiZWdpbiBjYWxjdWxhdGluZyBhbnlcbiAqIGhhc2hlcyBuZWVkZWQgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUuICBJdCBhbGxvd3MgdGhlIFNpZ25hdHVyZVxuICogcGFja2V0IHRvIGJlIHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLCBzbyB0aGF0IHRoZSBzaWduZXJcbiAqIGNhbiBjb21wdXRlIHRoZSBlbnRpcmUgc2lnbmVkIG1lc3NhZ2UgaW4gb25lIHBhc3MuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBvbmVfcGFzc19zaWduYXR1cmUoKSB7XG4gIHRoaXMudmVyc2lvbiA9IG51bGw7IC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuICB0aGlzLnR5cGUgPSBudWxsOyAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluIFJGQzQ4ODAgU2VjdGlvbiA1LjIuMS5cbiAgdGhpcy5oYXNoQWxnb3JpdGhtID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQuIChTZWUgUkZDNDg4MCA5LjQpXG4gIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIHVzZWQuIChTZWUgUkZDNDg4MCA5LjEpXG4gIHRoaXMuc2lnbmluZ0tleUlkID0gbnVsbDsgLy8gQW4gZWlnaHQtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgdGhlIEtleSBJRCBvZiB0aGUgc2lnbmluZyBrZXkuXG4gIHRoaXMuZmxhZ3MgPSBudWxsOyAvLyAgQSBvbmUtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgYSBmbGFnIHNob3dpbmcgd2hldGhlciB0aGUgc2lnbmF0dXJlIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXMgYW5vdGhlciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0IHRoYXQgZGVzY3JpYmVzIGFub3RoZXIgc2lnbmF0dXJlIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHNhbWUgbWVzc2FnZSBkYXRhLlxuXG4gIC8qKlxuICAgKiBwYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyA0KS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIHBheWxvYWQgb2YgYSB0YWcgNCBwYWNrZXRcbiAgICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9vbmVfcGFzc19zaWduYXR1cmV9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbXlwb3MgPSAwO1xuICAgIC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluXG4gICAgLy8gICBTZWN0aW9uIDUuMi4xLlxuICAgIHRoaXMudHlwZSA9IGVudW1zLnJlYWQoZW51bXMuc2lnbmF0dXJlLCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLlxuICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuaGFzaCwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gdXNlZC5cbiAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuICAgIC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICAgIHRoaXMuc2lnbmluZ0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgICB0aGlzLnNpZ25pbmdLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgIG15cG9zICs9IDg7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgaG9sZGluZyBhIGZsYWcgc2hvd2luZyB3aGV0aGVyIHRoZSBzaWduYXR1cmVcbiAgICAvLyAgIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXNcbiAgICAvLyAgIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyXG4gICAgLy8gICBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuXG4gICAgdGhpcy5mbGFncyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcblxuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDMpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy50eXBlKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtKSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSkpO1xuICAgIHJlc3VsdCArPSB0aGlzLnNpZ25pbmdLZXlJZC53cml0ZSgpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZmxhZ3MpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIHBhY2tldC9wYWNrZXQgKi9cblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmVhZFNpbXBsZUxlbmd0aDogZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbGVuID0gMCxcbiAgICAgIG9mZnNldCxcbiAgICAgIHR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KDApO1xuXG5cbiAgICBpZiAodHlwZSA8IDE5Mikge1xuICAgICAgbGVuID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcbiAgICAgIG9mZnNldCA9IDE7XG4gICAgfSBlbHNlIGlmICh0eXBlIDwgMjU1KSB7XG4gICAgICBsZW4gPSAoKGJ5dGVzLmNoYXJDb2RlQXQoMCkgLSAxOTIpIDw8IDgpICsgKGJ5dGVzLmNoYXJDb2RlQXQoMSkpICsgMTkyO1xuICAgICAgb2Zmc2V0ID0gMjtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gMjU1KSB7XG4gICAgICBsZW4gPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKDEsIDQpKTtcbiAgICAgIG9mZnNldCA9IDU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxlbjogbGVuLFxuICAgICAgb2Zmc2V0OiBvZmZzZXRcbiAgICB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBFbmNvZGVzIGEgZ2l2ZW4gaW50ZWdlciBvZiBsZW5ndGggdG8gdGhlIG9wZW5wZ3AgbGVuZ3RoIHNwZWNpZmllciB0byBhXG4gICAqIHN0cmluZ1xuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggVGhlIGxlbmd0aCB0byBlbmNvZGVcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgd2l0aCBvcGVucGdwIGxlbmd0aCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgd3JpdGVTaW1wbGVMZW5ndGg6IGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgIGlmIChsZW5ndGggPCAxOTIpIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbmd0aCk7XG4gICAgfSBlbHNlIGlmIChsZW5ndGggPiAxOTEgJiYgbGVuZ3RoIDwgODM4NCkge1xuICAgICAgLypcbiAgICAgICAqIGxldCBhID0gKHRvdGFsIGRhdGEgcGFja2V0IGxlbmd0aCkgLSAxOTIgbGV0IGJjID0gdHdvIG9jdGV0XG4gICAgICAgKiByZXByZXNlbnRhdGlvbiBvZiBhIGxldCBkID0gYiArIDE5MlxuICAgICAgICovXG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGxlbmd0aCAtIDE5MikgPj4gOCkgKyAxOTIpO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlbmd0aCAtIDE5MikgJiAweEZGKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU1KTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgNCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHBhY2tldCBoZWFkZXIgdmVyc2lvbiA0IHdpdGggdGhlIGdpdmVuIHRhZ190eXBlIGFuZCBsZW5ndGggdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdGFnX3R5cGUgVGFnIHR5cGVcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIG9mIHRoZSBwYXlsb2FkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIG9mIHRoZSBoZWFkZXJcbiAgICovXG4gIHdyaXRlSGVhZGVyOiBmdW5jdGlvbih0YWdfdHlwZSwgbGVuZ3RoKSB7XG4gICAgLyogd2UncmUgb25seSBnZW5lcmF0aW5nIHY0IHBhY2tldCBoZWFkZXJzIGhlcmUgKi9cbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweEMwIHwgdGFnX3R5cGUpO1xuICAgIHJlc3VsdCArPSB0aGlzLndyaXRlU2ltcGxlTGVuZ3RoKGxlbmd0aCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvKipcbiAgICogV3JpdGVzIGEgcGFja2V0IGhlYWRlciBWZXJzaW9uIDMgd2l0aCB0aGUgZ2l2ZW4gdGFnX3R5cGUgYW5kIGxlbmd0aCB0byBhXG4gICAqIHN0cmluZ1xuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0YWdfdHlwZSBUYWcgdHlwZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBMZW5ndGggb2YgdGhlIHBheWxvYWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgb2YgdGhlIGhlYWRlclxuICAgKi9cbiAgd3JpdGVPbGRIZWFkZXI6IGZ1bmN0aW9uKHRhZ190eXBlLCBsZW5ndGgpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICBpZiAobGVuZ3RoIDwgMjU2KSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbmd0aCk7XG4gICAgfSBlbHNlIGlmIChsZW5ndGggPCA2NTUzNikge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSB8IDEpO1xuICAgICAgcmVzdWx0ICs9IHV0aWwud3JpdGVOdW1iZXIobGVuZ3RoLCAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSB8IDIpO1xuICAgICAgcmVzdWx0ICs9IHV0aWwud3JpdGVOdW1iZXIobGVuZ3RoLCA0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvKipcbiAgICogR2VuZXJpYyBzdGF0aWMgUGFja2V0IFBhcnNlciBmdW5jdGlvblxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IElucHV0IHN0cmVhbSBhcyBzdHJpbmdcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCBwYXJzaW5nXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgaW5wdXQgZnJvbSBwb3NpdGlvbiBvblxuICAgKiBAcmV0dXJuIHtPYmplY3R9IFJldHVybnMgYSBwYXJzZWQgbW9kdWxlOnBhY2tldC9wYWNrZXRcbiAgICovXG4gIHJlYWQ6IGZ1bmN0aW9uKGlucHV0LCBwb3NpdGlvbiwgbGVuKSB7XG4gICAgLy8gc29tZSBzYW5pdHkgY2hlY2tzXG4gICAgaWYgKGlucHV0ID09IG51bGwgfHwgaW5wdXQubGVuZ3RoIDw9IHBvc2l0aW9uIHx8IGlucHV0LnN1YnN0cmluZyhwb3NpdGlvbikubGVuZ3RoIDwgMiB8fCAoaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgJlxuICAgICAgMHg4MCkgPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXJyb3IgZHVyaW5nIHBhcnNpbmcuIFRoaXMgbWVzc2FnZSAvIGtleSBpcyBwcm9iYWJseSBub3QgY29udGFpbmluZyBhIHZhbGlkIE9wZW5QR1AgZm9ybWF0LlwiKTtcbiAgICB9XG4gICAgdmFyIG15cG9zID0gcG9zaXRpb247XG4gICAgdmFyIHRhZyA9IC0xO1xuICAgIHZhciBmb3JtYXQgPSAtMTtcbiAgICB2YXIgcGFja2V0X2xlbmd0aDtcblxuICAgIGZvcm1hdCA9IDA7IC8vIDAgPSBvbGQgZm9ybWF0OyAxID0gbmV3IGZvcm1hdFxuICAgIGlmICgoaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDQwKSAhPSAwKSB7XG4gICAgICBmb3JtYXQgPSAxO1xuICAgIH1cblxuICAgIHZhciBwYWNrZXRfbGVuZ3RoX3R5cGU7XG4gICAgaWYgKGZvcm1hdCkge1xuICAgICAgLy8gbmV3IGZvcm1hdCBoZWFkZXJcbiAgICAgIHRhZyA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MpICYgMHgzRjsgLy8gYml0IDUtMFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBvbGQgZm9ybWF0IGhlYWRlclxuICAgICAgdGFnID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpICYgMHgzRikgPj4gMjsgLy8gYml0IDUtMlxuICAgICAgcGFja2V0X2xlbmd0aF90eXBlID0gaW5wdXQuY2hhckNvZGVBdChteXBvcykgJiAweDAzOyAvLyBiaXQgMS0wXG4gICAgfVxuXG4gICAgLy8gaGVhZGVyIG9jdGV0IHBhcnNpbmcgZG9uZVxuICAgIG15cG9zKys7XG5cbiAgICAvLyBwYXJzZWQgbGVuZ3RoIGZyb20gbGVuZ3RoIGZpZWxkXG4gICAgdmFyIGJvZHlkYXRhID0gbnVsbDtcblxuICAgIC8vIHVzZWQgZm9yIHBhcnRpYWwgYm9keSBsZW5ndGhzXG4gICAgdmFyIHJlYWxfcGFja2V0X2xlbmd0aCA9IC0xO1xuICAgIGlmICghZm9ybWF0KSB7XG4gICAgICAvLyA0LjIuMS4gT2xkIEZvcm1hdCBQYWNrZXQgTGVuZ3Roc1xuICAgICAgc3dpdGNoIChwYWNrZXRfbGVuZ3RoX3R5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIC8vIFRoZSBwYWNrZXQgaGFzIGEgb25lLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyAyIG9jdGV0c1xuICAgICAgICAgIC8vIGxvbmcuXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAvLyBUaGUgcGFja2V0IGhhcyBhIHR3by1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMyBvY3RldHNcbiAgICAgICAgICAvLyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCA4KSB8IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAvLyBUaGUgcGFja2V0IGhhcyBhIGZvdXItb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDVcbiAgICAgICAgICAvLyBvY3RldHMgbG9uZy5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMjQpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgMTYpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDxcbiAgICAgICAgICAgIDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyAzIC0gVGhlIHBhY2tldCBpcyBvZiBpbmRldGVybWluYXRlIGxlbmd0aC4gVGhlIGhlYWRlciBpcyAxXG4gICAgICAgICAgLy8gb2N0ZXQgbG9uZywgYW5kIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGRldGVybWluZSBob3cgbG9uZ1xuICAgICAgICAgIC8vIHRoZSBwYWNrZXQgaXMuIElmIHRoZSBwYWNrZXQgaXMgaW4gYSBmaWxlLCB0aGlzIG1lYW5zIHRoYXRcbiAgICAgICAgICAvLyB0aGUgcGFja2V0IGV4dGVuZHMgdW50aWwgdGhlIGVuZCBvZiB0aGUgZmlsZS4gSW4gZ2VuZXJhbCwgXG4gICAgICAgICAgLy8gYW4gaW1wbGVtZW50YXRpb24gU0hPVUxEIE5PVCB1c2UgaW5kZXRlcm1pbmF0ZS1sZW5ndGggXG4gICAgICAgICAgLy8gcGFja2V0cyBleGNlcHQgd2hlcmUgdGhlIGVuZCBvZiB0aGUgZGF0YSB3aWxsIGJlIGNsZWFyIFxuICAgICAgICAgIC8vIGZyb20gdGhlIGNvbnRleHQsIGFuZCBldmVuIHRoZW4gaXQgaXMgYmV0dGVyIHRvIHVzZSBhIFxuICAgICAgICAgIC8vIGRlZmluaXRlIGxlbmd0aCwgb3IgYSBuZXcgZm9ybWF0IGhlYWRlci4gVGhlIG5ldyBmb3JtYXQgXG4gICAgICAgICAgLy8gaGVhZGVycyBkZXNjcmliZWQgYmVsb3cgaGF2ZSBhIG1lY2hhbmlzbSBmb3IgcHJlY2lzZWx5XG4gICAgICAgICAgLy8gZW5jb2RpbmcgZGF0YSBvZiBpbmRldGVybWluYXRlIGxlbmd0aC5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gbGVuO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIC8vIDQuMi4yLiBOZXcgRm9ybWF0IFBhY2tldCBMZW5ndGhzXG4gICAge1xuXG4gICAgICAvLyA0LjIuMi4xLiBPbmUtT2N0ZXQgTGVuZ3Roc1xuICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpIDwgMTkyKSB7XG4gICAgICAgIHBhY2tldF9sZW5ndGggPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB1dGlsLnByaW50X2RlYnVnKFwiMSBieXRlIGxlbmd0aDpcIiArIHBhY2tldF9sZW5ndGgpO1xuICAgICAgICAvLyA0LjIuMi4yLiBUd28tT2N0ZXQgTGVuZ3Roc1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA+PSAxOTIgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvcykgPCAyMjQpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9ICgoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSAtIDE5MikgPDwgOCkgKyAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSkgKyAxOTI7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCIyIGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIDQuMi4yLjQuIFBhcnRpYWwgQm9keSBMZW5ndGhzXG4gICAgICB9IGVsc2UgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpID4gMjIzICYmIGlucHV0LmNoYXJDb2RlQXQobXlwb3MpIDwgMjU1KSB7XG4gICAgICAgIHBhY2tldF9sZW5ndGggPSAxIDw8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspICYgMHgxRik7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCI0IGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIEVFRUssIHdlJ3JlIHJlYWRpbmcgdGhlIGZ1bGwgZGF0YSBoZXJlLi4uXG4gICAgICAgIHZhciBteXBvczIgPSBteXBvcyArIHBhY2tldF9sZW5ndGg7XG4gICAgICAgIGJvZHlkYXRhID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLCBteXBvcyArIHBhY2tldF9sZW5ndGgpO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPCAxOTIpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKTtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIG15cG9zMiArPSB0bXBsZW47XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGVsc2UgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA+PSAxOTIgJiYgaW5wdXQuY2hhckNvZGVBdChteXBvczIpIDwgMjI0KSB7XG4gICAgICAgICAgICB2YXIgdG1wbGVuID0gKChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSAtIDE5MikgPDwgOCkgKyAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykpICsgMTkyO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvczIpID4gMjIzICYmIGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA8IDI1NSkge1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IDEgPDwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspICYgMHgxRik7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBteXBvczIrKztcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgPDwgMjQpIHwgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspIDw8IDE2KSB8IChpbnB1dFtteXBvczIrK11cbiAgICAgICAgICAgICAgLmNoYXJDb2RlQXQoKSA8PCA4KSB8IGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZWFsX3BhY2tldF9sZW5ndGggPSBteXBvczI7XG4gICAgICAgIC8vIDQuMi4yLjMuIEZpdmUtT2N0ZXQgTGVuZ3Roc1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXlwb3MrKztcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDI0KSB8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDE2KSB8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8XG4gICAgICAgICAgOCkgfCBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIHRoZXJlIHdhcydudCBhIHBhcnRpYWwgYm9keSBsZW5ndGg6IHVzZSB0aGUgc3BlY2lmaWVkXG4gICAgLy8gcGFja2V0X2xlbmd0aFxuICAgIGlmIChyZWFsX3BhY2tldF9sZW5ndGggPT0gLTEpIHtcbiAgICAgIHJlYWxfcGFja2V0X2xlbmd0aCA9IHBhY2tldF9sZW5ndGg7XG4gICAgfVxuXG4gICAgaWYgKGJvZHlkYXRhID09IG51bGwpIHtcbiAgICAgIGJvZHlkYXRhID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLCBteXBvcyArIHJlYWxfcGFja2V0X2xlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhZzogdGFnLFxuICAgICAgcGFja2V0OiBib2R5ZGF0YSxcbiAgICAgIG9mZnNldDogbXlwb3MgKyByZWFsX3BhY2tldF9sZW5ndGhcbiAgICB9O1xuICB9XG59XG4iLCIvKiogQG1vZHVsZSBwYWNrZXQvcGFja2V0bGlzdCAqL1xuXG52YXIgcGFja2V0UGFyc2VyID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcbiAgcGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsaXN0IG9mIG9wZW5wZ3AgcGFja2V0cy5cbiAqIFRha2UgY2FyZSB3aGVuIGl0ZXJhdGluZyBvdmVyIGl0IC0gdGhlIHBhY2tldHMgdGhlbXNlbHZlc1xuICogYXJlIHN0b3JlZCBhcyBudW1lcmljYWwgaW5kaWNlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRsaXN0KCkge1xuICAvKiogVGhlIG51bWJlciBvZiBwYWNrZXRzIGNvbnRhaW5lZCB3aXRoaW4gdGhlIGxpc3QuXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SW50ZWdlcn0gKi9cbiAgdGhpcy5sZW5ndGggPSAwO1xuXG4gIC8qKlxuICAgKiBSZWFkcyBhIHN0cmVhbSBvZiBiaW5hcnkgZGF0YSBhbmQgaW50ZXJwcmVudHMgaXQgYXMgYSBsaXN0IG9mIHBhY2tldHMuXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBBbiBhcnJheSBvZiBieXRlcy5cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHZhciBwYXJzZWQgPSBwYWNrZXRQYXJzZXIucmVhZChieXRlcywgaSwgYnl0ZXMubGVuZ3RoIC0gaSk7XG4gICAgICBpID0gcGFyc2VkLm9mZnNldDtcblxuICAgICAgdmFyIHRhZyA9IGVudW1zLnJlYWQoZW51bXMucGFja2V0LCBwYXJzZWQudGFnKTtcbiAgICAgIHZhciBwYWNrZXQgPSBuZXcgcGFja2V0c1t0YWddKCk7XG5cbiAgICAgIHRoaXMucHVzaChwYWNrZXQpO1xuXG4gICAgICBwYWNrZXQucmVhZChwYXJzZWQucGFja2V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGJpbmFyeSByZXByZXNlbnRhdGlvbiBvZiBvcGVucGdwIG9iamVjdHMgY29udGFpbmVkIHdpdGhpbiB0aGVcbiAgICogY2xhc3MgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtvcGVucGdwX2J5dGVfYXJyYXl9IEFuIGFycmF5IG9mIGJ5dGVzIGNvbnRhaW5pbmcgdmFsaWQgb3BlbnBncCBwYWNrZXRzLlxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBieXRlcyA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcGFja2V0Ynl0ZXMgPSB0aGlzW2ldLndyaXRlKCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRQYXJzZXIud3JpdGVIZWFkZXIodGhpc1tpXS50YWcsIHBhY2tldGJ5dGVzLmxlbmd0aCk7XG4gICAgICBieXRlcyArPSBwYWNrZXRieXRlcztcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBhY2tldCB0byB0aGUgbGlzdC4gVGhpcyBpcyB0aGUgb25seSBzdXBwb3J0ZWQgbWV0aG9kIG9mIGRvaW5nIHNvO1xuICAgKiB3cml0aW5nIHRvIHBhY2tldGxpc3RbaV0gZGlyZWN0bHkgd2lsbCByZXN1bHQgaW4gYW4gZXJyb3IuXG4gICAqL1xuICB0aGlzLnB1c2ggPSBmdW5jdGlvbihwYWNrZXQpIHtcbiAgICBpZiAoIXBhY2tldCkgcmV0dXJuO1xuXG4gICAgcGFja2V0LnBhY2tldHMgPSBwYWNrZXQucGFja2V0cyB8fCBuZXcgcGFja2V0bGlzdCgpO1xuXG4gICAgdGhpc1t0aGlzLmxlbmd0aF0gPSBwYWNrZXQ7XG4gICAgdGhpcy5sZW5ndGgrKztcbiAgfVxuXG4gIC8qKlxuICAqIENyZWF0ZXMgYSBuZXcgcGFja2V0TGlzdCB3aXRoIGFsbCBwYWNrZXRzIHRoYXQgcGFzcyB0aGUgdGVzdCBpbXBsZW1lbnRlZCBieSB0aGUgcHJvdmlkZWQgZnVuY3Rpb24uXG4gICovXG4gIHRoaXMuZmlsdGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcblxuICAgIHZhciBmaWx0ZXJlZCA9IG5ldyBwYWNrZXRsaXN0KCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChjYWxsYmFjayh0aGlzW2ldLCBpLCB0aGlzKSkge1xuICAgICAgICBmaWx0ZXJlZC5wdXNoKHRoaXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgfVxuXG4gIC8qKlxuICAqIENyZWF0ZXMgYSBuZXcgcGFja2V0TGlzdCB3aXRoIGFsbCBwYWNrZXRzIGZyb20gdGhlIGdpdmVuIHR5cGVzXG4gICovXG4gIHRoaXMuZmlsdGVyQnlUYWcgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgdmFyIGZpbHRlcmVkID0gbmV3IHBhY2tldGxpc3QoKTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcmdzLnNvbWUoZnVuY3Rpb24ocGFja2V0VHlwZSkge3JldHVybiB0aGF0W2ldLnRhZyA9PSBwYWNrZXRUeXBlfSkpIHtcbiAgICAgICAgZmlsdGVyZWQucHVzaCh0aGlzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyZWQ7XG4gIH0gXG5cbiAgLyoqXG4gICogRXhlY3V0ZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrIG9uY2UgZm9yIGVhY2ggZWxlbWVudFxuICAqL1xuICB0aGlzLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgY2FsbGJhY2sodGhpc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyBwYWNrZXQgdHJlZSBhbmQgcmV0dXJucyBmaXJzdCBtYXRjaGluZyBwYWNrZXRcbiAgICogQHBhcmFtICB7bW9kdWxlOmVudW1zLnBhY2tldH0gdHlwZSBUaGUgcGFja2V0IHR5cGVcbiAgICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9wYWNrZXR8bnVsbH0gICAgICBcbiAgICovXG4gIHRoaXMuZmluZFBhY2tldCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICB2YXIgcGFja2V0bGlzdCA9IHRoaXMuZmlsdGVyQnlUYWcodHlwZSk7XG4gICAgaWYgKHBhY2tldGxpc3QubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gcGFja2V0bGlzdFswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZvdW5kID0gbnVsbDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpc1tpXS5wYWNrZXRzLmxlbmd0aCkge1xuICAgICAgICAgIGZvdW5kID0gdGhpc1tpXS5wYWNrZXRzLmZpbmRQYWNrZXQodHlwZSk7XG4gICAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhcnJheSBvZiBmb3VuZCBpbmRpY2VzIGJ5IHRhZ1xuICAgKi9cbiAgdGhpcy5pbmRleE9mVGFnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHZhciB0YWdJbmRleCA9IFtdO1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcmdzLnNvbWUoZnVuY3Rpb24ocGFja2V0VHlwZSkge3JldHVybiB0aGF0W2ldLnRhZyA9PSBwYWNrZXRUeXBlfSkpIHtcbiAgICAgICAgdGFnSW5kZXgucHVzaChpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhZ0luZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgc2xpY2Ugb2YgcGFja2V0bGlzdFxuICAgKi9cbiAgdGhpcy5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcbiAgICBpZiAoIWVuZCkge1xuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgdmFyIHBhcnQgPSBuZXcgcGFja2V0bGlzdCgpO1xuICAgIGZvciAodmFyIGkgPSBiZWdpbjsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICBwYXJ0LnB1c2godGhpc1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmNhdGVuYXRlcyBwYWNrZXRsaXN0IG9yIGFycmF5IG9mIHBhY2tldHNcbiAgICovXG4gIHRoaXMuY29uY2F0ID0gZnVuY3Rpb24ocGFja2V0bGlzdCkge1xuICAgIGlmIChwYWNrZXRsaXN0KSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhY2tldGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5wdXNoKHBhY2tldGxpc3RbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvcHVibGljX2tleSAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogICBcbiAqIFJGQzQ0ODAgNS41OlxuICogQSBrZXkgbWF0ZXJpYWwgcGFja2V0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgYSBwdWJsaWMgb3JcbiAqIHByaXZhdGUga2V5LiAgVGhlcmUgYXJlIGZvdXIgdmFyaWFudHMgb2YgdGhpcyBwYWNrZXQgdHlwZSwgYW5kIHR3b1xuICogbWFqb3IgdmVyc2lvbnMuICBDb25zZXF1ZW50bHksIHRoaXMgc2VjdGlvbiBpcyBjb21wbGV4LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5KCkge1xuICB0aGlzLnZlcnNpb24gPSA0O1xuICAvKiogS2V5IGNyZWF0aW9uIGRhdGUuXG4gICAqIEB0eXBlIHtEYXRlfSAqL1xuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICAvKiogQSBsaXN0IG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEB0eXBlIHttb2R1bGU6dHlwZS9tcGl9ICovXG4gIHRoaXMubXBpID0gW107XG4gIC8qKiBQdWJsaWMga2V5IGFsZ29yaXRobVxuICAgKiBAdHlwZSB7b3BlbnBncC5wdWJsaWNrZXl9ICovXG4gIHRoaXMuYWxnb3JpdGhtID0gJ3JzYV9zaWduJztcbiAgLy8gdGltZSBpbiBkYXlzIChWMyBvbmx5KVxuICB0aGlzLmV4cGlyYXRpb25UaW1lVjMgPSAwO1xuXG5cbiAgLyoqXG4gICAqIEludGVybmFsIFBhcnNlciBmb3IgcHVibGljIGtleXMgYXMgc3BlY2lmaWVkIGluIFJGQyA0ODgwIHNlY3Rpb24gXG4gICAqIDUuNS4yIFB1YmxpYy1LZXkgUGFja2V0IEZvcm1hdHNcbiAgICogY2FsbGVkIGJ5IHJlYWRfdGFnJmx0O251bSZndDtcbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IElucHV0IHN0cmluZyB0byByZWFkIHRoZSBwYWNrZXQgZnJvbVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFN0YXJ0IHBvc2l0aW9uIGZvciB0aGUgcGFyc2VyXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHJlbWFpbmluZyBsZW5ndGggb2YgaW5wdXRcbiAgICogQHJldHVybiB7T2JqZWN0fSBUaGlzIG9iamVjdCB3aXRoIGF0dHJpYnV0ZXMgc2V0IGJ5IHRoZSBwYXJzZXJcbiAgICovXG4gIHRoaXMucmVhZFB1YmxpY0tleSA9IHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgLy8gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIgKDMgb3IgNCkuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdChwb3MrKyk7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09IDMgfHwgdGhpcy52ZXJzaW9uID09IDQpIHtcbiAgICAgIC8vIC0gQSBmb3VyLW9jdGV0IG51bWJlciBkZW5vdGluZyB0aGUgdGltZSB0aGF0IHRoZSBrZXkgd2FzIGNyZWF0ZWQuXG4gICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihwb3MsIDQpKTtcbiAgICAgIHBvcyArPSA0O1xuXG4gICAgICBpZiAodGhpcy52ZXJzaW9uID09IDMpIHtcbiAgICAgICAgLy8gLSBBIHR3by1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHRpbWUgaW4gZGF5cyB0aGF0IHRoaXMga2V5IGlzXG4gICAgICAgIC8vICAgdmFsaWQuICBJZiB0aGlzIG51bWJlciBpcyB6ZXJvLCB0aGVuIGl0IGRvZXMgbm90IGV4cGlyZS5cbiAgICAgICAgdGhpcy5leHBpcmF0aW9uVGltZVYzID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihwb3MsIDIpKTtcbiAgICAgICAgcG9zICs9IDI7XG4gICAgICB9XG5cbiAgICAgIC8vIC0gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSBvZiB0aGlzIGtleS5cbiAgICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzLmNoYXJDb2RlQXQocG9zKyspKTtcblxuICAgICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIHRoaXMubXBpID0gW107XG5cbiAgICAgIHZhciBibXBpID0gYnl0ZXMuc3Vic3RyKHBvcyk7XG4gICAgICB2YXIgcCA9IDA7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpY291bnQgJiYgcCA8IGJtcGkubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICB0aGlzLm1waVtpXSA9IG5ldyB0eXBlX21waSgpO1xuXG4gICAgICAgIHAgKz0gdGhpcy5tcGlbaV0ucmVhZChibXBpLnN1YnN0cihwKSlcblxuICAgICAgICBpZiAocCA+IGJtcGkubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciByZWFkaW5nIE1QSSBAOicgKyBwKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcCArIDY7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVmVyc2lvbiAnICsgdmVyc2lvbiArICcgb2YgdGhlIGtleSBwYWNrZXQgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogU2FtZSBhcyB3cml0ZV9wcml2YXRlX2tleSwgYnV0IGhhcyBsZXNzIGluZm9ybWF0aW9uIGJlY2F1c2Ugb2YgXG4gICAqIHB1YmxpYyBrZXkuXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0ga2V5VHlwZSBGb2xsb3dzIHRoZSBPcGVuUEdQIGFsZ29yaXRobSBzdGFuZGFyZCwgXG4gICAqIElFIDEgY29ycmVzcG9uZHMgdG8gUlNBLlxuICAgKiBAcGFyYW0ge1JTQS5rZXlPYmplY3R9IGtleVxuICAgKiBAcGFyYW0gdGltZVBhY2tldFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IHtib2R5OiBbc3RyaW5nXU9wZW5QR1AgcGFja2V0IGJvZHkgY29udGVudHMsIFxuICAgKiBoZWFkZXI6IFtzdHJpbmddIE9wZW5QR1AgcGFja2V0IGhlYWRlciwgc3RyaW5nOiBbc3RyaW5nXSBoZWFkZXIrYm9keX1cbiAgICovXG4gIHRoaXMud3JpdGVQdWJsaWNLZXkgPSB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gVmVyc2lvblxuICAgIHZhciByZXN1bHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudmVyc2lvbik7XG4gICAgcmVzdWx0ICs9IHV0aWwud3JpdGVEYXRlKHRoaXMuY3JlYXRlZCk7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PSAzKSB7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLmV4cGlyYXRpb25UaW1lVjMsIDIpO1xuICAgIH1cbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMuYWxnb3JpdGhtKSk7XG5cbiAgICB2YXIgbXBpY291bnQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQodGhpcy5hbGdvcml0aG0pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5tcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gV3JpdGUgYW4gb2xkIHZlcnNpb24gcGFja2V0IC0gaXQncyB1c2VkIGJ5IHNvbWUgb2YgdGhlIGludGVybmFsIHJvdXRpbmVzLlxuICB0aGlzLndyaXRlT2xkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkgK1xuICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDIpICtcbiAgICAgIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGtleSBpZCBvZiB0aGUga2V5IFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgOCBieXRlIGtleSBpZFxuICAgKi9cbiAgdGhpcy5nZXRLZXlJZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBrZXlpZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PSA0KSB7XG4gICAgICBrZXlpZC5yZWFkKHRoaXMuZ2V0RmluZ2VycHJpbnQoKS5zdWJzdHIoMTIsIDgpKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmVyc2lvbiA9PSAzKSB7XG4gICAgICBrZXlpZC5yZWFkKHRoaXMubXBpWzBdLndyaXRlKCkuc3Vic3RyKC04KSk7XG4gICAgfVxuICAgIHJldHVybiBrZXlpZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBmaW5nZXJwcmludCBvZiB0aGUga2V5XG4gICAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgZmluZ2VycHJpbnRcbiAgICovXG4gIHRoaXMuZ2V0RmluZ2VycHJpbnQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgdG9IYXNoID0gJyc7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PSA0KSB7XG4gICAgICB0b0hhc2ggPSB0aGlzLndyaXRlT2xkKCk7XG4gICAgICByZXR1cm4gY3J5cHRvLmhhc2guc2hhMSh0b0hhc2gpO1xuICAgIH0gZWxzZSBpZiAodGhpcy52ZXJzaW9uID09IDMpIHtcbiAgICAgIHZhciBtcGljb3VudCA9IGNyeXB0by5nZXRQdWJsaWNNcGlDb3VudCh0aGlzLmFsZ29yaXRobSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1waWNvdW50OyBpKyspIHtcbiAgICAgICAgdG9IYXNoICs9IHRoaXMubXBpW2ldLnRvQnl0ZXMoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5tZDUodG9IYXNoKVxuICAgIH1cbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkgKi9cblxudmFyIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBQYWNrZXRzIChUYWcgMSlcbiAqIFxuICogUkZDNDg4MCA1LjE6IEEgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0IGhvbGRzIHRoZSBzZXNzaW9uIGtleVxuICogdXNlZCB0byBlbmNyeXB0IGEgbWVzc2FnZS4gWmVybyBvciBtb3JlIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5XG4gKiBwYWNrZXRzIGFuZC9vciBTeW1tZXRyaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXRzIG1heSBwcmVjZWRlIGFcbiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCB3aGljaCBob2xkcyBhbiBlbmNyeXB0ZWQgbWVzc2FnZS4gVGhlXG4gKiBtZXNzYWdlIGlzIGVuY3J5cHRlZCB3aXRoIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZSBzZXNzaW9uIGtleSBpcyBpdHNlbGZcbiAqIGVuY3J5cHRlZCBhbmQgc3RvcmVkIGluIHRoZSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0KHMpLiBUaGVcbiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0IGlzIHByZWNlZGVkIGJ5IG9uZSBQdWJsaWMtS2V5IEVuY3J5cHRlZFxuICogU2Vzc2lvbiBLZXkgcGFja2V0IGZvciBlYWNoIE9wZW5QR1Aga2V5IHRvIHdoaWNoIHRoZSBtZXNzYWdlIGlzIGVuY3J5cHRlZC5cbiAqIFRoZSByZWNpcGllbnQgb2YgdGhlIG1lc3NhZ2UgZmluZHMgYSBzZXNzaW9uIGtleSB0aGF0IGlzIGVuY3J5cHRlZCB0byB0aGVpclxuICogcHVibGljIGtleSwgZGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlbiB1c2VzIHRoZSBzZXNzaW9uIGtleSB0b1xuICogZGVjcnlwdCB0aGUgbWVzc2FnZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSB7XG4gIHRoaXMudmVyc2lvbiA9IDM7XG5cbiAgdGhpcy5wdWJsaWNLZXlJZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gJ3JzYV9lbmNyeXB0JztcblxuICB0aGlzLnNlc3Npb25LZXkgPSBudWxsO1xuICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSAnYWVzMjU2JztcblxuICAvKiogQHR5cGUge0FycmF5PG1vZHVsZTp0eXBlL21waT59ICovXG4gIHRoaXMuZW5jcnlwdGVkID0gW107XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgcHVibGlja2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAxKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5fSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cbiAgICB0aGlzLnZlcnNpb24gPSBieXRlcy5jaGFyQ29kZUF0KDApO1xuICAgIHRoaXMucHVibGljS2V5SWQucmVhZChieXRlcy5zdWJzdHIoMSkpO1xuICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzLmNoYXJDb2RlQXQoOSkpO1xuXG4gICAgdmFyIGkgPSAxMDtcblxuICAgIHZhciBpbnRlZ2VyQ291bnQgPSAoZnVuY3Rpb24oYWxnbykge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgICAgcmV0dXJuIDE7XG5cbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgcmV0dXJuIDI7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGFsZ29yaXRobS5cIik7XG4gICAgICB9XG4gICAgfSkodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pO1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBbXTtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgaW50ZWdlckNvdW50OyBqKyspIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGkgKz0gbXBpLnJlYWQoYnl0ZXMuc3Vic3RyKGkpKTtcbiAgICAgIHRoaXMuZW5jcnlwdGVkLnB1c2gobXBpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHVibGljS2V5SWRcbiAgICogICAgICAgICAgICAgVGhlIHB1YmxpYyBrZXkgaWQgY29ycmVzcG9uZGluZyB0byBwdWJsaWNNUElzIGtleSBhcyBzdHJpbmdcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzXG4gICAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwdWJhbGdvXG4gICAqICAgICAgICAgICAgVGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBhbGdvcml0aG0gLy8gU2VlIFJGQzQ4ODAgOS4xXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ29cbiAgICogICAgICAgICAgICBUaGUgc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhIFxuICAgKiAgICAgICAgICAgIHdpdGhpbiBhbiBlbmNyeXB0ZWRkYXRhcGFja2V0IG9yIGVuY3J5cHRlZGludGVncml0eS1cbiAgICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IFxuICAgKiAgICAgICAgICAgIGZvbGxvd2luZyB0aGlzIHBhY2tldCAvL1NlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2Vzc2lvbmtleVxuICAgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pO1xuICAgIHJlc3VsdCArPSB0aGlzLnB1YmxpY0tleUlkLndyaXRlKCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW5jcnlwdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5lbmNyeXB0ZWRbaV0ud3JpdGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgZGF0YSArPSB0aGlzLnNlc3Npb25LZXk7XG4gICAgdmFyIGNoZWNrc3VtID0gdXRpbC5jYWxjX2NoZWNrc3VtKHRoaXMuc2Vzc2lvbktleSk7XG4gICAgZGF0YSArPSB1dGlsLndyaXRlTnVtYmVyKGNoZWNrc3VtLCAyKTtcblxuICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICBtcGkuZnJvbUJ5dGVzKGNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKFxuICAgICAgZGF0YSxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5wdWJsaWNLZXlFbmNyeXB0KFxuICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBrZXkubXBpLFxuICAgICAgbXBpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqIHBhY2tldHMgKHRhZyAxKVxuICAgKiBcbiAgICogQHBhcmFtIHttb2R1bGU6cGFja2V0L3NlY3JldF9rZXl9IGtleVxuICAgKiAgICAgICAgICAgIFByaXZhdGUga2V5IHdpdGggc2VjTVBJcyB1bmxvY2tlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSB1bmVuY3J5cHRlZCBzZXNzaW9uIGtleVxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIHJlc3VsdCA9IGNyeXB0by5wdWJsaWNLZXlEZWNyeXB0KFxuICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBrZXkubXBpLFxuICAgICAgdGhpcy5lbmNyeXB0ZWQpLnRvQnl0ZXMoKTtcblxuICAgIHZhciBjaGVja3N1bSA9IHV0aWwucmVhZE51bWJlcihyZXN1bHQuc3Vic3RyKHJlc3VsdC5sZW5ndGggLSAyKSk7XG5cbiAgICB2YXIgZGVjb2RlZCA9IGNyeXB0by5wa2NzMS5lbWUuZGVjb2RlKFxuICAgICAgcmVzdWx0LFxuICAgICAga2V5Lm1waVswXS5ieXRlTGVuZ3RoKCkpO1xuXG4gICAgdmFyIGtleSA9IGRlY29kZWQuc3Vic3RyaW5nKDEsIGRlY29kZWQubGVuZ3RoIC0gMik7XG5cbiAgICBpZiAoY2hlY2tzdW0gIT0gdXRpbC5jYWxjX2NoZWNrc3VtKGtleSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2tzdW0gbWlzbWF0Y2gnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXNzaW9uS2V5ID0ga2V5O1xuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID1cbiAgICAgICAgZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGRlY29kZWQuY2hhckNvZGVBdCgwKSk7XG4gICAgfVxuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgcGFja2V0L3B1YmxpY19zdWJrZXkgKi9cblxudmFyIHB1YmxpY19rZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwdWJsaWNfc3Via2V5KCkge1xuICBwdWJsaWNfa2V5LmNhbGwodGhpcyk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvc2VjcmV0X2tleSAqL1xuXG52YXIgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKSxcbiAgdHlwZV9zMmsgPSByZXF1aXJlKCcuLi90eXBlL3Myay5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogQGV4dGVuZHMgbW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5XG4gKiAgIFxuICogUkZDNDQ4MCA1LjU6XG4gKiBBIGtleSBtYXRlcmlhbCBwYWNrZXQgY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIHB1YmxpYyBvclxuICogcHJpdmF0ZSBrZXkuICBUaGVyZSBhcmUgZm91ciB2YXJpYW50cyBvZiB0aGlzIHBhY2tldCB0eXBlLCBhbmQgdHdvXG4gKiBtYWpvciB2ZXJzaW9ucy4gIENvbnNlcXVlbnRseSwgdGhpcyBzZWN0aW9uIGlzIGNvbXBsZXguXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICBwdWJsaWNLZXkuY2FsbCh0aGlzKTtcbiAgLy8gZW5jcnlwdGVkIHNlY3JldC1rZXkgZGF0YVxuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIC8vIGluZGljYXRvciBpZiBzZWNyZXQta2V5IGRhdGEgaXMgYXZhaWxhYmxlIGluIGRlY3J5cHRlZCBmb3JtXG4gIHRoaXMuaXNEZWNyeXB0ZWQgPSBmYWxzZTtcblxuXG4gIGZ1bmN0aW9uIGdldF9oYXNoX2xlbihoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT0gJ3NoYTEnKVxuICAgICAgcmV0dXJuIDIwO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiAyO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0X2hhc2hfZm4oaGFzaCkge1xuICAgIGlmIChoYXNoID09ICdzaGExJylcbiAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5zaGExO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiB1dGlsLndyaXRlTnVtYmVyKHV0aWwuY2FsY19jaGVja3N1bShjKSwgMik7XG4gICAgfTtcbiAgfVxuXG4gIC8vIEhlbHBlciBmdW5jdGlvblxuXG4gIGZ1bmN0aW9uIHBhcnNlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGNsZWFydGV4dCwgYWxnb3JpdGhtKSB7XG4gICAgdmFyIGhhc2hsZW4gPSBnZXRfaGFzaF9sZW4oaGFzaF9hbGdvcml0aG0pLFxuICAgICAgaGFzaGZuID0gZ2V0X2hhc2hfZm4oaGFzaF9hbGdvcml0aG0pO1xuXG4gICAgdmFyIGhhc2h0ZXh0ID0gY2xlYXJ0ZXh0LnN1YnN0cihjbGVhcnRleHQubGVuZ3RoIC0gaGFzaGxlbik7XG4gICAgY2xlYXJ0ZXh0ID0gY2xlYXJ0ZXh0LnN1YnN0cigwLCBjbGVhcnRleHQubGVuZ3RoIC0gaGFzaGxlbik7XG5cbiAgICB2YXIgaGFzaCA9IGhhc2hmbihjbGVhcnRleHQpO1xuXG4gICAgaWYgKGhhc2ggIT0gaGFzaHRleHQpXG4gICAgICByZXR1cm4gbmV3IEVycm9yKFwiSGFzaCBtaXNtYXRjaC5cIik7XG5cbiAgICB2YXIgbXBpcyA9IGNyeXB0by5nZXRQcml2YXRlTXBpQ291bnQoYWxnb3JpdGhtKTtcblxuICAgIHZhciBqID0gMDtcbiAgICB2YXIgbXBpID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1waXMgJiYgaiA8IGNsZWFydGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgbXBpW2ldID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBqICs9IG1waVtpXS5yZWFkKGNsZWFydGV4dC5zdWJzdHIoaikpO1xuICAgIH1cblxuICAgIHJldHVybiBtcGk7XG4gIH1cblxuICBmdW5jdGlvbiB3cml0ZV9jbGVhcnRleHRfbXBpKGhhc2hfYWxnb3JpdGhtLCBhbGdvcml0aG0sIG1waSkge1xuICAgIHZhciBieXRlcyA9ICcnO1xuICAgIHZhciBkaXNjYXJkID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KGFsZ29yaXRobSk7XG5cbiAgICBmb3IgKHZhciBpID0gZGlzY2FyZDsgaSA8IG1waS5sZW5ndGg7IGkrKykge1xuICAgICAgYnl0ZXMgKz0gbXBpW2ldLndyaXRlKCk7XG4gICAgfVxuXG5cbiAgICBieXRlcyArPSBnZXRfaGFzaF9mbihoYXNoX2FsZ29yaXRobSkoYnl0ZXMpO1xuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cblxuICAvLyA1LjUuMy4gIFNlY3JldC1LZXkgUGFja2V0IEZvcm1hdHNcblxuICAvKipcbiAgICogSW50ZXJuYWwgcGFyc2VyIGZvciBwcml2YXRlIGtleXMgYXMgc3BlY2lmaWVkIGluIFJGQyA0ODgwIHNlY3Rpb24gNS41LjNcbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIElucHV0IHN0cmluZyB0byByZWFkIHRoZSBwYWNrZXQgZnJvbVxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyAtIEEgUHVibGljLUtleSBvciBQdWJsaWMtU3Via2V5IHBhY2tldCwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgIHZhciBsZW4gPSB0aGlzLnJlYWRQdWJsaWNLZXkoYnl0ZXMpO1xuXG4gICAgYnl0ZXMgPSBieXRlcy5zdWJzdHIobGVuKTtcblxuXG4gICAgLy8gLSBPbmUgb2N0ZXQgaW5kaWNhdGluZyBzdHJpbmctdG8ta2V5IHVzYWdlIGNvbnZlbnRpb25zLiAgWmVyb1xuICAgIC8vICAgaW5kaWNhdGVzIHRoYXQgdGhlIHNlY3JldC1rZXkgZGF0YSBpcyBub3QgZW5jcnlwdGVkLiAgMjU1IG9yIDI1NFxuICAgIC8vICAgaW5kaWNhdGVzIHRoYXQgYSBzdHJpbmctdG8ta2V5IHNwZWNpZmllciBpcyBiZWluZyBnaXZlbi4gIEFueVxuICAgIC8vICAgb3RoZXIgdmFsdWUgaXMgYSBzeW1tZXRyaWMta2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIGlkZW50aWZpZXIuXG4gICAgdmFyIGlzRW5jcnlwdGVkID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIGlmIChpc0VuY3J5cHRlZCkge1xuICAgICAgdGhpcy5lbmNyeXB0ZWQgPSBieXRlcztcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyAtIFBsYWluIG9yIGVuY3J5cHRlZCBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBzZWNyZXRcbiAgICAgIC8vICAga2V5IGRhdGEuICBUaGVzZSBhbGdvcml0aG0tc3BlY2lmaWMgZmllbGRzIGFyZSBhcyBkZXNjcmliZWRcbiAgICAgIC8vICAgYmVsb3cuXG4gICAgICB2YXIgcGFyc2VkTVBJID0gcGFyc2VfY2xlYXJ0ZXh0X21waSgnbW9kJywgYnl0ZXMuc3Vic3RyKDEpLCB0aGlzLmFsZ29yaXRobSk7XG4gICAgICBpZiAocGFyc2VkTVBJIGluc3RhbmNlb2YgRXJyb3IpXG4gICAgICAgIHRocm93IHBhcnNlZE1QSTtcbiAgICAgIHRoaXMubXBpID0gdGhpcy5tcGkuY29uY2F0KHBhcnNlZE1QSSk7XG4gICAgICB0aGlzLmlzRGVjcnlwdGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgfTtcblxuICAvKiogQ3JlYXRlcyBhbiBPcGVuUEdQIGtleSBwYWNrZXQgZm9yIHRoZSBnaXZlbiBrZXkuXG4gICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgc3RyaW5nIG9mIGJ5dGVzIGNvbnRhaW5pbmcgdGhlIHNlY3JldCBrZXkgT3BlblBHUCBwYWNrZXRcbiAgICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG4gICAgaWYgKCF0aGlzLmVuY3J5cHRlZCkge1xuICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcblxuICAgICAgYnl0ZXMgKz0gd3JpdGVfY2xlYXJ0ZXh0X21waSgnbW9kJywgdGhpcy5hbGdvcml0aG0sIHRoaXMubXBpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnl0ZXMgKz0gdGhpcy5lbmNyeXB0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9O1xuXG5cblxuXG4gIC8qKiBFbmNyeXB0IHRoZSBwYXlsb2FkLiBCeSBkZWZhdWx0LCB3ZSB1c2UgYWVzMjU2IGFuZCBpdGVyYXRlZCwgc2FsdGVkIHN0cmluZ1xuICAgKiB0byBrZXkgc3BlY2lmaWVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlXG4gICAqL1xuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG5cbiAgICB2YXIgczJrID0gbmV3IHR5cGVfczJrKCksXG4gICAgICBzeW1tZXRyaWMgPSAnYWVzMjU2JyxcbiAgICAgIGNsZWFydGV4dCA9IHdyaXRlX2NsZWFydGV4dF9tcGkoJ3NoYTEnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpLFxuICAgICAga2V5ID0gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBzeW1tZXRyaWMpLFxuICAgICAgYmxvY2tMZW4gPSBjcnlwdG8uY2lwaGVyW3N5bW1ldHJpY10uYmxvY2tTaXplLFxuICAgICAgaXYgPSBjcnlwdG8ucmFuZG9tLmdldFJhbmRvbUJ5dGVzKGJsb2NrTGVuKTtcblxuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSAnJztcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NCk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHN5bW1ldHJpYykpO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IHMyay53cml0ZSgpO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IGl2O1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gY3J5cHRvLmNmYi5ub3JtYWxFbmNyeXB0KHN5bW1ldHJpYywga2V5LCBjbGVhcnRleHQsIGl2KTtcbiAgfTtcblxuICBmdW5jdGlvbiBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIGFsZ29yaXRobSkge1xuICAgIHJldHVybiBzMmsucHJvZHVjZV9rZXkocGFzc3BocmFzZSxcbiAgICAgIGNyeXB0by5jaXBoZXJbYWxnb3JpdGhtXS5rZXlTaXplKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgcHJpdmF0ZSBrZXkgTVBJcyB3aGljaCBhcmUgbmVlZGVkIHRvIHVzZSB0aGUga2V5LlxuICAgKiBvcGVucGdwX3BhY2tldF9rZXltYXRlcmlhbC5oYXNVbmVuY3J5cHRlZFNlY3JldEtleURhdGEgc2hvdWxkIGJlIFxuICAgKiBmYWxzZSBvdGhlcndpc2VcbiAgICogYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24gaXMgbm90IG5lZWRlZFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0cl9wYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIGZvciB0aGlzIHByaXZhdGUga2V5IFxuICAgKiBhcyBzdHJpbmdcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc3BocmFzZSB3YXMgY29ycmVjdCBvciBNUEkgYWxyZWFkeVxuICAgKiAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWQ7IGZhbHNlIGlmIG5vdFxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICAgIGlmICh0aGlzLmlzRGVjcnlwdGVkKVxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICB2YXIgaSA9IDAsXG4gICAgICBzeW1tZXRyaWMsXG4gICAgICBrZXk7XG5cbiAgICB2YXIgczJrX3VzYWdlID0gdGhpcy5lbmNyeXB0ZWQuY2hhckNvZGVBdChpKyspO1xuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXQgd2FzIDI1NSBvciAyNTQsIGEgb25lLVxuICAgIC8vICAgb2N0ZXQgc3ltbWV0cmljIGVuY3J5cHRpb24gYWxnb3JpdGhtLlxuICAgIGlmIChzMmtfdXNhZ2UgPT0gMjU1IHx8IHMya191c2FnZSA9PSAyNTQpIHtcbiAgICAgIHN5bW1ldHJpYyA9IHRoaXMuZW5jcnlwdGVkLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuXG4gICAgICAvLyAtIFtPcHRpb25hbF0gSWYgc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldCB3YXMgMjU1IG9yIDI1NCwgYVxuICAgICAgLy8gICBzdHJpbmctdG8ta2V5IHNwZWNpZmllci4gIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy10by1rZXlcbiAgICAgIC8vICAgc3BlY2lmaWVyIGlzIGltcGxpZWQgYnkgaXRzIHR5cGUsIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgICAgIHZhciBzMmsgPSBuZXcgdHlwZV9zMmsoKTtcbiAgICAgIGkgKz0gczJrLnJlYWQodGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpKTtcblxuICAgICAga2V5ID0gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBzeW1tZXRyaWMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzeW1tZXRyaWMgPSBzMmtfdXNhZ2U7XG4gICAgICBzeW1tZXRyaWMgPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKTtcbiAgICAgIGtleSA9IGNyeXB0by5oYXNoLm1kNShwYXNzcGhyYXNlKTtcbiAgICB9XG5cblxuICAgIC8vIC0gW09wdGlvbmFsXSBJZiBzZWNyZXQgZGF0YSBpcyBlbmNyeXB0ZWQgKHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXRcbiAgICAvLyAgIG5vdCB6ZXJvKSwgYW4gSW5pdGlhbCBWZWN0b3IgKElWKSBvZiB0aGUgc2FtZSBsZW5ndGggYXMgdGhlXG4gICAgLy8gICBjaXBoZXIncyBibG9jayBzaXplLlxuICAgIHZhciBpdiA9IHRoaXMuZW5jcnlwdGVkLnN1YnN0cihpLFxuICAgICAgY3J5cHRvLmNpcGhlcltzeW1tZXRyaWNdLmJsb2NrU2l6ZSk7XG5cbiAgICBpICs9IGl2Lmxlbmd0aDtcblxuICAgIHZhciBjbGVhcnRleHQsXG4gICAgICBjaXBoZXJ0ZXh0ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpO1xuXG4gICAgY2xlYXJ0ZXh0ID0gY3J5cHRvLmNmYi5ub3JtYWxEZWNyeXB0KHN5bW1ldHJpYywga2V5LCBjaXBoZXJ0ZXh0LCBpdik7XG5cbiAgICB2YXIgaGFzaCA9IHMya191c2FnZSA9PSAyNTQgP1xuICAgICAgJ3NoYTEnIDpcbiAgICAgICdtb2QnO1xuXG4gICAgdmFyIHBhcnNlZE1QSSA9IHBhcnNlX2NsZWFydGV4dF9tcGkoaGFzaCwgY2xlYXJ0ZXh0LCB0aGlzLmFsZ29yaXRobSk7XG4gICAgaWYgKHBhcnNlZE1QSSBpbnN0YW5jZW9mIEVycm9yKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHRoaXMubXBpID0gdGhpcy5tcGkuY29uY2F0KHBhcnNlZE1QSSk7XG4gICAgdGhpcy5pc0RlY3J5cHRlZCA9IHRydWU7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgdGhpcy5nZW5lcmF0ZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICB0aGlzLm1waSA9IGNyeXB0by5nZW5lcmF0ZU1waSh0aGlzLmFsZ29yaXRobSwgYml0cyk7XG4gICAgdGhpcy5pc0RlY3J5cHRlZCA9IHRydWU7XG4gIH07XG5cbn1cblxubW9kdWxlLmV4cG9ydHMucHJvdG90eXBlID0gbmV3IHB1YmxpY0tleSgpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgcGFja2V0L3NlY3JldF9zdWJrZXkgKi9cblxudmFyIHNlY3JldF9rZXkgPSByZXF1aXJlKCcuL3NlY3JldF9rZXkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzZWNyZXRfc3Via2V5KCkge1xuICBzZWNyZXRfa2V5LmNhbGwodGhpcyk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvc2lnbmF0dXJlICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTaWduYXR1cmUgUGFja2V0IChUYWcgMilcbiAqIFxuICogUkZDNDQ4MCA1LjI6XG4gKiBBIFNpZ25hdHVyZSBwYWNrZXQgZGVzY3JpYmVzIGEgYmluZGluZyBiZXR3ZWVuIHNvbWUgcHVibGljIGtleSBhbmRcbiAqIHNvbWUgZGF0YS4gIFRoZSBtb3N0IGNvbW1vbiBzaWduYXR1cmVzIGFyZSBhIHNpZ25hdHVyZSBvZiBhIGZpbGUgb3IgYVxuICogYmxvY2sgb2YgdGV4dCwgYW5kIGEgc2lnbmF0dXJlIHRoYXQgaXMgYSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc2lnbmF0dXJlKCkge1xuXG4gIHRoaXMudmVyc2lvbiA9IDQ7XG4gIHRoaXMuc2lnbmF0dXJlVHlwZSA9IG51bGw7XG4gIHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDtcblxuICB0aGlzLnNpZ25hdHVyZURhdGEgPSBudWxsO1xuICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IG51bGw7XG4gIHRoaXMubXBpID0gbnVsbDtcblxuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICB0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMgPSB0cnVlO1xuICB0aGlzLmV4cG9ydGFibGUgPSBudWxsO1xuICB0aGlzLnRydXN0TGV2ZWwgPSBudWxsO1xuICB0aGlzLnRydXN0QW1vdW50ID0gbnVsbDtcbiAgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IG51bGw7XG4gIHRoaXMucmV2b2NhYmxlID0gbnVsbDtcbiAgdGhpcy5rZXlFeHBpcmF0aW9uVGltZSA9IG51bGw7XG4gIHRoaXMua2V5TmV2ZXJFeHBpcmVzID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgPSBudWxsO1xuICB0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBudWxsO1xuICB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludCA9IG51bGw7XG4gIHRoaXMuaXNzdWVyS2V5SWQgPSBuZXcgdHlwZV9rZXlpZCgpO1xuICB0aGlzLm5vdGF0aW9uID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zID0gbnVsbDtcbiAgdGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkS2V5U2VydmVyID0gbnVsbDtcbiAgdGhpcy5pc1ByaW1hcnlVc2VySUQgPSBudWxsO1xuICB0aGlzLnBvbGljeVVSSSA9IG51bGw7XG4gIHRoaXMua2V5RmxhZ3MgPSBudWxsO1xuICB0aGlzLnNpZ25lcnNVc2VySWQgPSBudWxsO1xuICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnID0gbnVsbDtcbiAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nID0gbnVsbDtcbiAgdGhpcy5mZWF0dXJlcyA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoID0gbnVsbDtcbiAgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG51bGw7XG5cbiAgdGhpcy52ZXJpZmllZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBwYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyAyKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIHBheWxvYWQgb2YgYSB0YWcgMiBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGJ5dGVzIHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBieXRlcyBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L3NpZ25hdHVyZX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNClcbiAgICBzd2l0Y2ggKHRoaXMudmVyc2lvbikge1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuIE1VU1QgYmUgNS5cbiAgICAgICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSAhPSA1KVxuICAgICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIiArXG4gICAgICAgICAgICAnaW52YWxpZCBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuJyArXG4gICAgICAgICAgICAnTVVTVCBiZSA1LiBAOicgKyAoaSAtIDEpKTtcblxuICAgICAgICB2YXIgc2lncG9zID0gaTtcbiAgICAgICAgLy8gT25lLW9jdGV0IHNpZ25hdHVyZSB0eXBlLlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gRm91ci1vY3RldCBjcmVhdGlvbiB0aW1lLlxuICAgICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihpLCA0KSk7XG4gICAgICAgIGkgKz0gNDtcblxuICAgICAgICAvLyBzdG9yaW5nIGRhdGEgYXBwZW5kZWQgdG8gZGF0YSB3aGljaCBnZXRzIHZlcmlmaWVkXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSA9IGJ5dGVzLnN1YnN0cmluZyhzaWdwb3MsIGkpO1xuXG4gICAgICAgIC8vIEVpZ2h0LW9jdGV0IEtleSBJRCBvZiBzaWduZXIuXG4gICAgICAgIHRoaXMuaXNzdWVyS2V5SWQucmVhZChieXRlcy5zdWJzdHJpbmcoaSwgaSArIDgpKTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9uZS1vY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobS5cbiAgICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgLy8gT25lLW9jdGV0IGhhc2ggYWxnb3JpdGhtLlxuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgICAgZnVuY3Rpb24gc3VicGFja2V0cyhieXRlcykge1xuICAgICAgICAgIC8vIFR3by1vY3RldCBzY2FsYXIgb2N0ZXQgY291bnQgZm9yIGZvbGxvd2luZyBzdWJwYWNrZXQgZGF0YS5cbiAgICAgICAgICB2YXIgc3VicGFja2V0X2xlbmd0aCA9IHV0aWwucmVhZE51bWJlcihcbiAgICAgICAgICAgIGJ5dGVzLnN1YnN0cigwLCAyKSk7XG5cbiAgICAgICAgICB2YXIgaSA9IDI7XG5cbiAgICAgICAgICAvLyBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKVxuICAgICAgICAgIHZhciBzdWJwYWNrZWRfcmVhZCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGkgPCAyICsgc3VicGFja2V0X2xlbmd0aCkge1xuXG4gICAgICAgICAgICB2YXIgbGVuID0gcGFja2V0LnJlYWRTaW1wbGVMZW5ndGgoYnl0ZXMuc3Vic3RyKGkpKTtcbiAgICAgICAgICAgIGkgKz0gbGVuLm9mZnNldDtcblxuICAgICAgICAgICAgdGhpcy5yZWFkX3N1Yl9wYWNrZXQoYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcblxuICAgICAgICAgICAgaSArPSBsZW4ubGVuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCB0cnVlKTtcblxuICAgICAgICAvLyBBIFY0IHNpZ25hdHVyZSBoYXNoZXMgdGhlIHBhY2tldCBib2R5XG4gICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gaXRzIGZpcnN0IGZpZWxkLCB0aGUgdmVyc2lvbiBudW1iZXIsIHRocm91Z2ggdGhlIGVuZFxuICAgICAgICAvLyBvZiB0aGUgaGFzaGVkIHN1YnBhY2tldCBkYXRhLiAgVGh1cywgdGhlIGZpZWxkcyBoYXNoZWQgYXJlIHRoZVxuICAgICAgICAvLyBzaWduYXR1cmUgdmVyc2lvbiwgdGhlIHNpZ25hdHVyZSB0eXBlLCB0aGUgcHVibGljLWtleSBhbGdvcml0aG0sIHRoZVxuICAgICAgICAvLyBoYXNoIGFsZ29yaXRobSwgdGhlIGhhc2hlZCBzdWJwYWNrZXQgbGVuZ3RoLCBhbmQgdGhlIGhhc2hlZFxuICAgICAgICAvLyBzdWJwYWNrZXQgYm9keS5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVEYXRhID0gYnl0ZXMuc3Vic3RyKDAsIGkpO1xuXG4gICAgICAgIC8vIHVuaGFzaGVkIHN1YnBhY2tldHNcbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCBmYWxzZSk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBzaWduYXR1cmUgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFR3by1vY3RldCBmaWVsZCBob2xkaW5nIGxlZnQgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS5cbiAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IGJ5dGVzLnN1YnN0cihpLCAyKTtcbiAgICBpICs9IDI7XG5cbiAgICB0aGlzLnNpZ25hdHVyZSA9IGJ5dGVzLnN1YnN0cihpKTtcbiAgfTtcblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuc2lnbmF0dXJlRGF0YSArXG4gICAgICB1dGlsLndyaXRlTnVtYmVyKDAsIDIpICsgLy8gTnVtYmVyIG9mIHVuc2lnbmVkIHN1YnBhY2tldHMuXG4gICAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSArXG4gICAgICB0aGlzLnNpZ25hdHVyZTtcbiAgfTtcblxuICAvKipcbiAgICogU2lnbnMgcHJvdmlkZWQgZGF0YS4gVGhpcyBuZWVkcyB0byBiZSBkb25lIHByaW9yIHRvIHNlcmlhbGl6YXRpb24uXG4gICAqIEBwYXJhbSB7bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fSBrZXkgcHJpdmF0ZSBrZXkgdXNlZCB0byBzaWduIHRoZSBtZXNzYWdlLiBcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgQ29udGFpbnMgcGFja2V0cyB0byBiZSBzaWduZWQuXG4gICAqL1xuICB0aGlzLnNpZ24gPSBmdW5jdGlvbihrZXksIGRhdGEpIHtcbiAgICB2YXIgc2lnbmF0dXJlVHlwZSA9IGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy5zaWduYXR1cmVUeXBlKSxcbiAgICAgIHB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pLFxuICAgICAgaGFzaEFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSk7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaWduYXR1cmVUeXBlKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwdWJsaWNLZXlBbGdvcml0aG0pO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGhhc2hBbGdvcml0aG0pO1xuXG4gICAgdGhpcy5pc3N1ZXJLZXlJZCA9IGtleS5nZXRLZXlJZCgpO1xuXG4gICAgLy8gQWRkIGhhc2hlZCBzdWJwYWNrZXRzXG4gICAgcmVzdWx0ICs9IHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzKCk7XG5cbiAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSByZXN1bHQ7XG5cbiAgICB2YXIgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXG4gICAgdmFyIHRvSGFzaCA9IHRoaXMudG9TaWduKHNpZ25hdHVyZVR5cGUsIGRhdGEpICtcbiAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXI7XG5cbiAgICB2YXIgaGFzaCA9IGNyeXB0by5oYXNoLmRpZ2VzdChoYXNoQWxnb3JpdGhtLCB0b0hhc2gpO1xuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBoYXNoLnN1YnN0cigwLCAyKTtcblxuICAgIHRoaXMuc2lnbmF0dXJlID0gY3J5cHRvLnNpZ25hdHVyZS5zaWduKGhhc2hBbGdvcml0aG0sXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0sIGtleS5tcGksIHRvSGFzaCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgc3RyaW5nIG9mIGJ5dGVzIHdpdGggYWxsIHN1YnBhY2tldCBkYXRhXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgYSBhbGwgc3VicGFja2V0IGRhdGFcbiAgICovXG4gIHRoaXMud3JpdGVfYWxsX3N1Yl9wYWNrZXRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN1YiA9IGVudW1zLnNpZ25hdHVyZVN1YnBhY2tldDtcbiAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgaWYgKHRoaXMuY3JlYXRlZCAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25hdHVyZV9jcmVhdGlvbl90aW1lLCB1dGlsLndyaXRlRGF0ZSh0aGlzLmNyZWF0ZWQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduYXR1cmVfZXhwaXJhdGlvbl90aW1lLCB1dGlsLndyaXRlTnVtYmVyKHRoaXMuc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUsIDQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZXhwb3J0YWJsZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmV4cG9ydGFibGVfY2VydGlmaWNhdGlvbiwgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmV4cG9ydGFibGUgPyAxIDogMCkpO1xuICAgIH1cbiAgICBpZiAodGhpcy50cnVzdExldmVsICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy50cnVzdExldmVsKSArIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy50cnVzdEFtb3VudCk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIudHJ1c3Rfc2lnbmF0dXJlLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnJlZ3VsYXJFeHByZXNzaW9uICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucmVndWxhcl9leHByZXNzaW9uLCB0aGlzLnJlZ3VsYXJFeHByZXNzaW9uKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucmV2b2NhYmxlICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucmV2b2NhYmxlLCBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmV2b2NhYmxlID8gMSA6IDApKTtcbiAgICB9XG4gICAgaWYgKHRoaXMua2V5RXhwaXJhdGlvblRpbWUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5rZXlfZXhwaXJhdGlvbl90aW1lLCB1dGlsLndyaXRlTnVtYmVyKHRoaXMua2V5RXhwaXJhdGlvblRpbWUsIDQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmVmZXJyZWRfc3ltbWV0cmljX2FsZ29yaXRobXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucmV2b2NhdGlvbktleUNsYXNzICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MpO1xuICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0pO1xuICAgICAgYnl0ZXMgKz0gdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQ7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucmV2b2NhdGlvbl9rZXksIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmlzc3VlcktleUlkLmlzTnVsbCgpKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuaXNzdWVyLCB0aGlzLmlzc3VlcktleUlkLndyaXRlKCkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5ub3RhdGlvbiAhPT0gbnVsbCkge1xuICAgICAgZm9yICh2YXIgbmFtZSBpbiB0aGlzLm5vdGF0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLm5vdGF0aW9uLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5ub3RhdGlvbltuYW1lXTtcbiAgICAgICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCk7XG4gICAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICAgICAgLy8gMiBvY3RldHMgb2YgbmFtZSBsZW5ndGhcbiAgICAgICAgICBieXRlcyArPSB1dGlsLndyaXRlTnVtYmVyKG5hbWUubGVuZ3RoLCAyKTtcbiAgICAgICAgICAvLyAyIG9jdGV0cyBvZiB2YWx1ZSBsZW5ndGhcbiAgICAgICAgICBieXRlcyArPSB1dGlsLndyaXRlTnVtYmVyKHZhbHVlLmxlbmd0aCwgMik7XG4gICAgICAgICAgYnl0ZXMgKz0gbmFtZSArIHZhbHVlO1xuICAgICAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5ub3RhdGlvbl9kYXRhLCBieXRlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IFxuICAgIGlmICh0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmVmZXJyZWRfaGFzaF9hbGdvcml0aG1zLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9oYXNoX2FsZ29yaXRobXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMua2V5U2VydmVyUHJlZmVyZW5jZXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMua2V5U2VydmVyUHJlZmVyZW5jZXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmtleV9zZXJ2ZXJfcHJlZmVyZW5jZXMsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJlZmVycmVkS2V5U2VydmVyICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJlZmVycmVkX2tleV9zZXJ2ZXIsIHRoaXMucHJlZmVycmVkS2V5U2VydmVyKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNQcmltYXJ5VXNlcklEICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJpbWFyeV91c2VyX2lkLCBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuaXNQcmltYXJ5VXNlcklEID8gMSA6IDApKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucG9saWN5VVJJICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucG9saWN5X3VyaSwgdGhpcy5wb2xpY3lVUkkpOyBcbiAgICB9XG4gICAgaWYgKHRoaXMua2V5RmxhZ3MgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMua2V5RmxhZ3MpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmtleV9mbGFncywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5zaWduZXJzVXNlcklkICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuc2lnbmVyc191c2VyX2lkLCB0aGlzLnNpZ25lcnNVc2VySWQpOyBcbiAgICB9XG4gICAgaWYgKHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnKTtcbiAgICAgIGJ5dGVzICs9IHRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZztcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5yZWFzb25fZm9yX3Jldm9jYXRpb24sIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZmVhdHVyZXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMuZmVhdHVyZXMpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmZlYXR1cmVzLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtKTtcbiAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtKTtcbiAgICAgIGJ5dGVzICs9IHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaDtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduYXR1cmVfdGFyZ2V0LCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmVtYmVkZGVkU2lnbmF0dXJlICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuZW1iZWRkZWRfc2lnbmF0dXJlLCB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLndyaXRlKCkpO1xuICAgIH1cbiAgICByZXN1bHQgPSB1dGlsLndyaXRlTnVtYmVyKHJlc3VsdC5sZW5ndGgsIDIpICsgcmVzdWx0O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBzdWIgc2lnbmF0dXJlIHBhY2tldCAoU2VlIFJGQyA0ODgwIDUuMi4zLjEpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBzdWJwYWNrZXQgc2lnbmF0dXJlIHR5cGUuIFNpZ25hdHVyZSB0eXBlcyBhcyBkZXNjcmliZWQgXG4gICAqIGluIFJGQzQ4ODAgU2VjdGlvbiA1LjIuMy4yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIGRhdGEgdG8gYmUgaW5jbHVkZWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZy1yZXByZXNlbnRhdGlvbiBvZiBhIHN1YiBzaWduYXR1cmUgcGFja2V0IChTZWUgUkZDIDQ4ODAgNS4yLjMuMSlcbiAgICovXG4gIGZ1bmN0aW9uIHdyaXRlX3N1Yl9wYWNrZXQodHlwZSwgZGF0YSkge1xuICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgIHJlc3VsdCArPSBwYWNrZXQud3JpdGVTaW1wbGVMZW5ndGgoZGF0YS5sZW5ndGggKyAxKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0eXBlKTtcbiAgICByZXN1bHQgKz0gZGF0YTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gVjQgc2lnbmF0dXJlIHN1YiBwYWNrZXRzXG5cbiAgdGhpcy5yZWFkX3N1Yl9wYWNrZXQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBteXBvcyA9IDA7XG5cbiAgICBmdW5jdGlvbiByZWFkX2FycmF5KHByb3AsIGJ5dGVzKSB7XG4gICAgICB0aGlzW3Byb3BdID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1twcm9wXS5wdXNoKGJ5dGVzLmNoYXJDb2RlQXQoaSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoZSBsZWZ0d29zdCBiaXQgZGVub3RlcyBhIFwiY3JpdGljYWxcIiBwYWNrZXQsIGJ1dCB3ZSBpZ25vcmUgaXQuXG4gICAgdmFyIHR5cGUgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspICYgMHg3RjtcblxuICAgIC8vIHN1YnBhY2tldCB0eXBlXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIFNpZ25hdHVyZSBDcmVhdGlvbiBUaW1lXG4gICAgICAgIHRoaXMuY3JlYXRlZCA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBTaWduYXR1cmUgRXhwaXJhdGlvbiBUaW1lIGluIHNlY29uZHNcbiAgICAgICAgdmFyIHNlY29uZHMgPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMgPSBzZWNvbmRzID09IDA7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlRXhwaXJhdGlvblRpbWUgPSBzZWNvbmRzO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA0OlxuICAgICAgICAvLyBFeHBvcnRhYmxlIENlcnRpZmljYXRpb25cbiAgICAgICAgdGhpcy5leHBvcnRhYmxlID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSA9PSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNTpcbiAgICAgICAgLy8gVHJ1c3QgU2lnbmF0dXJlXG4gICAgICAgIHRoaXMudHJ1c3RMZXZlbCA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMudHJ1c3RBbW91bnQgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjpcbiAgICAgICAgLy8gUmVndWxhciBFeHByZXNzaW9uXG4gICAgICAgIHRoaXMucmVndWxhckV4cHJlc3Npb24gPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNzpcbiAgICAgICAgLy8gUmV2b2NhYmxlXG4gICAgICAgIHRoaXMucmV2b2NhYmxlID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSA9PSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgLy8gS2V5IEV4cGlyYXRpb24gVGltZSBpbiBzZWNvbmRzXG4gICAgICAgIHZhciBzZWNvbmRzID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBzZWNvbmRzO1xuICAgICAgICB0aGlzLmtleU5ldmVyRXhwaXJlcyA9IHNlY29uZHMgPT0gMDtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIC8vIFByZWZlcnJlZCBTeW1tZXRyaWMgQWxnb3JpdGhtc1xuICAgICAgICB0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgPSBbXTtcblxuICAgICAgICB3aGlsZSAobXlwb3MgIT0gYnl0ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zLnB1c2goYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI6XG4gICAgICAgIC8vIFJldm9jYXRpb24gS2V5XG4gICAgICAgIC8vICgxIG9jdGV0IG9mIGNsYXNzLCAxIG9jdGV0IG9mIHB1YmxpYy1rZXkgYWxnb3JpdGhtIElELCAyMFxuICAgICAgICAvLyBvY3RldHMgb2ZcbiAgICAgICAgLy8gZmluZ2VycHJpbnQpXG4gICAgICAgIHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBieXRlcy5zdWJzdHIobXlwb3MsIDIwKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgMTY6XG4gICAgICAgIC8vIElzc3VlclxuICAgICAgICB0aGlzLmlzc3VlcktleUlkLnJlYWQoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDIwOlxuICAgICAgICAvLyBOb3RhdGlvbiBEYXRhXG4gICAgICAgIC8vIFdlIGRvbid0IGtub3cgaG93IHRvIGhhbmRsZSBhbnl0aGluZyBidXQgYSB0ZXh0IGZsYWdnZWQgZGF0YS5cbiAgICAgICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MpID09IDB4ODApIHtcblxuICAgICAgICAgIC8vIFdlIGV4dHJhY3Qga2V5L3ZhbHVlIHR1cGxlIGZyb20gdGhlIGJ5dGUgc3RyZWFtLlxuICAgICAgICAgIG15cG9zICs9IDQ7XG4gICAgICAgICAgdmFyIG0gPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zLCAyKSk7XG4gICAgICAgICAgbXlwb3MgKz0gMlxuICAgICAgICAgIHZhciBuID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihteXBvcywgMikpO1xuICAgICAgICAgIG15cG9zICs9IDJcblxuICAgICAgICAgIHZhciBuYW1lID0gYnl0ZXMuc3Vic3RyKG15cG9zLCBtKSxcbiAgICAgICAgICAgIHZhbHVlID0gYnl0ZXMuc3Vic3RyKG15cG9zICsgbSwgbik7XG5cbiAgICAgICAgICB0aGlzLm5vdGF0aW9uID0gdGhpcy5ub3RhdGlvbiB8fCB7fTtcbiAgICAgICAgICB0aGlzLm5vdGF0aW9uW25hbWVdID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBub3RhdGlvbiBmbGFnLlwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDIxOlxuICAgICAgICAvLyBQcmVmZXJyZWQgSGFzaCBBbGdvcml0aG1zXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAncHJlZmVycmVkSGFzaEFsZ29yaXRobXMnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDIyOlxuICAgICAgICAvLyBQcmVmZXJyZWQgQ29tcHJlc3Npb24gQWxnb3JpdGhtc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ3ByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyAnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDIzOlxuICAgICAgICAvLyBLZXkgU2VydmVyIFByZWZlcmVuY2VzXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAna2V5U2VydmVyUHJlZmVyZW5jZXNzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNDpcbiAgICAgICAgLy8gUHJlZmVycmVkIEtleSBTZXJ2ZXJcbiAgICAgICAgdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjU6XG4gICAgICAgIC8vIFByaW1hcnkgVXNlciBJRFxuICAgICAgICB0aGlzLmlzUHJpbWFyeVVzZXJJRCA9IGJ5dGVzW215cG9zKytdICE9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNjpcbiAgICAgICAgLy8gUG9saWN5IFVSSVxuICAgICAgICB0aGlzLnBvbGljeVVSSSA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyNzpcbiAgICAgICAgLy8gS2V5IEZsYWdzXG4gICAgICAgIHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAna2V5RmxhZ3MnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI4OlxuICAgICAgICAvLyBTaWduZXIncyBVc2VyIElEXG4gICAgICAgIHRoaXMuc2lnbmVyc1VzZXJJZCArPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjk6XG4gICAgICAgIC8vIFJlYXNvbiBmb3IgUmV2b2NhdGlvblxuICAgICAgICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMwOlxuICAgICAgICAvLyBGZWF0dXJlc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2ZlYXR1cmVzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMTpcbiAgICAgICAgLy8gU2lnbmF0dXJlIFRhcmdldFxuICAgICAgICAvLyAoMSBvY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobSwgMSBvY3RldCBoYXNoIGFsZ29yaXRobSwgTiBvY3RldHMgaGFzaClcbiAgICAgICAgdGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2hBbGdvcml0aG0gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuXG4gICAgICAgIHZhciBsZW4gPSBjcnlwdG8uZ2V0SGFzaEJ5dGVMZW5ndGgodGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtKTtcblxuICAgICAgICB0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2ggPSBieXRlcy5zdWJzdHIobXlwb3MsIGxlbik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjpcbiAgICAgICAgLy8gRW1iZWRkZWQgU2lnbmF0dXJlXG4gICAgICAgIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBuZXcgcGFja2V0X3NpZ25hdHVyZSgpO1xuICAgICAgICB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLnJlYWQoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzaWduYXR1cmUgc3VicGFja2V0IHR5cGUgXCIgKyB0eXBlICsgXCIgQDpcIiArIG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9O1xuXG4gIC8vIFByb2R1Y2VzIGRhdGEgdG8gcHJvZHVjZSBzaWduYXR1cmUgb25cbiAgdGhpcy50b1NpZ24gPSBmdW5jdGlvbih0eXBlLCBkYXRhKSB7XG4gICAgdmFyIHQgPSBlbnVtcy5zaWduYXR1cmU7XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgdC5iaW5hcnk6XG4gICAgICBjYXNlIHQudGV4dDpcbiAgICAgICAgcmV0dXJuIGRhdGEuZ2V0Qnl0ZXMoKTtcblxuICAgICAgY2FzZSB0LnN0YW5kYWxvbmU6XG4gICAgICAgIHJldHVybiAnJztcblxuICAgICAgY2FzZSB0LmNlcnRfZ2VuZXJpYzpcbiAgICAgIGNhc2UgdC5jZXJ0X3BlcnNvbmE6XG4gICAgICBjYXNlIHQuY2VydF9jYXN1YWw6XG4gICAgICBjYXNlIHQuY2VydF9wb3NpdGl2ZTpcbiAgICAgIGNhc2UgdC5jZXJ0X3Jldm9jYXRpb246XG4gICAgICAgIHZhciBwYWNrZXQsIHRhZztcblxuICAgICAgICBpZiAoZGF0YS51c2VyaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRhZyA9IDB4QjQ7XG4gICAgICAgICAgcGFja2V0ID0gZGF0YS51c2VyaWQ7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YS51c2VyYXR0cmlidXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0YWcgPSAweEQxO1xuICAgICAgICAgIHBhY2tldCA9IGRhdGEudXNlcmF0dHJpYnV0ZTtcbiAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcignRWl0aGVyIGEgdXNlcmlkIG9yIHVzZXJhdHRyaWJ1dGUgcGFja2V0IG5lZWRzIHRvIGJlICcgK1xuICAgICAgICAgICAgJ3N1cHBsaWVkIGZvciBjZXJ0aWZpY2F0aW9uLicpO1xuXG4gICAgICAgIHZhciBieXRlcyA9IHBhY2tldC53cml0ZSgpO1xuXG4gICAgICAgIGlmICh0aGlzLnZlcnNpb24gPT0gNCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSkgK1xuICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUodGFnKSArXG4gICAgICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDQpICtcbiAgICAgICAgICBieXRlczsgXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy52ZXJzaW9uID09IDMpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICtcbiAgICAgICAgICBieXRlcztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSB0LnN1YmtleV9iaW5kaW5nOlxuICAgICAgY2FzZSB0LmtleV9iaW5kaW5nOlxuICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICsgdGhpcy50b1NpZ24odC5rZXksIHtcbiAgICAgICAgICBrZXk6IGRhdGEuYmluZFxuICAgICAgICB9KTtcblxuICAgICAgY2FzZSB0LmtleTpcbiAgICAgICAgaWYgKGRhdGEua2V5ID09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0tleSBwYWNrZXQgaXMgcmVxdWlyZWQgZm9yIHRoaXMgc2lndGF0dXJlLicpO1xuXG4gICAgICAgIHJldHVybiBkYXRhLmtleS53cml0ZU9sZCgpO1xuXG4gICAgICBjYXNlIHQua2V5X3Jldm9jYXRpb246XG4gICAgICBjYXNlIHQuc3Via2V5X3Jldm9jYXRpb246XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSk7XG4gICAgICBjYXNlIHQudGltZXN0YW1wOlxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICBjYXNlIHQudGhpcmRfcGFydHk6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHNpZ25hdHVyZSB0eXBlLicpXG4gICAgfVxuICB9XG5cblxuICB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlclxuICAgIHZhciB0cmFpbGVyID0gJyc7XG4gICAgLy8gVjMgc2lnbmF0dXJlcyBkb24ndCBoYXZlIGEgdHJhaWxlclxuICAgIGlmICh0aGlzLnZlcnNpb24gPT0gMykgcmV0dXJuIHRyYWlsZXI7XG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOyAvLyBWZXJzaW9uXG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpO1xuICAgIHRyYWlsZXIgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZURhdGEubGVuZ3RoLCA0KTtcbiAgICByZXR1cm4gdHJhaWxlclxuICB9XG5cblxuICAvKipcbiAgICogdmVyaWZ5cyB0aGUgc2lnbmF0dXJlIHBhY2tldC4gTm90ZTogbm90IHNpZ25hdHVyZSB0eXBlcyBhcmUgaW1wbGVtZW50ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBkYXRhIGRhdGEgd2hpY2ggb24gdGhlIHNpZ25hdHVyZSBhcHBsaWVzXG4gICAqIEBwYXJhbSB7bW9kdWxlOnBhY2tldC9wdWJsaWNfc3Via2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0ga2V5IHRoZSBwdWJsaWMga2V5IHRvIHZlcmlmeSB0aGUgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbWVzc2FnZSBpcyB2ZXJpZmllZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIGJ5dGVzID0gdGhpcy50b1NpZ24oc2lnbmF0dXJlVHlwZSwgZGF0YSksXG4gICAgICB0cmFpbGVyID0gdGhpcy5jYWxjdWxhdGVUcmFpbGVyKCk7XG5cblxuICAgIHZhciBtcGljb3VudCA9IDA7XG4gICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHNpZ25hdHVyZXM6XG4gICAgLy8gICAgICAtIG11bHRpcHJlY2lzaW9uIG51bWJlciAoTVBJKSBvZiBSU0Egc2lnbmF0dXJlIHZhbHVlIG0qKmQgbW9kIG4uXG4gICAgaWYgKHB1YmxpY0tleUFsZ29yaXRobSA+IDAgJiYgcHVibGljS2V5QWxnb3JpdGhtIDwgNClcbiAgICAgIG1waWNvdW50ID0gMTtcbiAgICAvLyAgICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2lnbmF0dXJlczpcbiAgICAvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSByLlxuICAgIC8vICAgICAgLSBNUEkgb2YgRFNBIHZhbHVlIHMuXG4gICAgZWxzZSBpZiAocHVibGljS2V5QWxnb3JpdGhtID09IDE3KVxuICAgICAgbXBpY291bnQgPSAyO1xuXG4gICAgdmFyIG1waSA9IFtdLFxuICAgICAgaSA9IDA7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBtcGljb3VudDsgaisrKSB7XG4gICAgICBtcGlbal0gPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGkgKz0gbXBpW2pdLnJlYWQodGhpcy5zaWduYXR1cmUuc3Vic3RyKGkpKTtcbiAgICB9XG5cbiAgICB0aGlzLnZlcmlmaWVkID0gY3J5cHRvLnNpZ25hdHVyZS52ZXJpZnkocHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAgaGFzaEFsZ29yaXRobSwgbXBpLCBrZXkubXBpLFxuICAgICAgYnl0ZXMgKyB0aGlzLnNpZ25hdHVyZURhdGEgKyB0cmFpbGVyKTtcblxuICAgIHJldHVybiB0aGlzLnZlcmlmaWVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHNpZ25hdHVyZSBleHBpcmF0aW9uIGRhdGVcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiBleHBpcmVkXG4gICAqL1xuICB0aGlzLmlzRXhwaXJlZCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICghdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMpIHtcbiAgICAgIHJldHVybiBEYXRlLm5vdygpID4gKHRoaXMuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKjEwMDApO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIHBhY2tldC9zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQgKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltLiBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIFxuICogUGFja2V0IChUYWcgMTgpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xMzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQgaXNcbiAqIGEgdmFyaWFudCBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQuIEl0IGlzIGEgbmV3IGZlYXR1cmVcbiAqIGNyZWF0ZWQgZm9yIE9wZW5QR1AgdGhhdCBhZGRyZXNzZXMgdGhlIHByb2JsZW0gb2YgZGV0ZWN0aW5nIGEgbW9kaWZpY2F0aW9uIHRvXG4gKiBlbmNyeXB0ZWQgZGF0YS4gSXQgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGEgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlXG4gKiBwYWNrZXQuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCkge1xuICAvKiogVGhlIGVuY3J5cHRlZCBwYXlsb2FkLiAqL1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7IC8vIHN0cmluZ1xuICAvKipcbiAgICogSWYgYWZ0ZXIgZGVjcnlwdGluZyB0aGUgcGFja2V0IHRoaXMgaXMgc2V0IHRvIHRydWUsXG4gICAqIGEgbW9kaWZpY2F0aW9uIGhhcyBiZWVuIGRldGVjdGVkIGFuZCB0aHVzIHRoZSBjb250ZW50c1xuICAgKiBzaG91bGQgYmUgZGlzY2FyZGVkLlxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICovXG4gIHRoaXMubW9kaWZpY2F0aW9uID0gZmFsc2U7XG4gIHRoaXMucGFja2V0cztcblxuXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXNcbiAgICAvLyAxLlxuICAgIHZhciB2ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIGlmICh2ZXJzaW9uICE9IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYWNrZXQgdmVyc2lvbi4nKTtcbiAgICB9XG5cbiAgICAvLyAtIEVuY3J5cHRlZCBkYXRhLCB0aGUgb3V0cHV0IG9mIHRoZSBzZWxlY3RlZCBzeW1tZXRyaWMta2V5IGNpcGhlclxuICAgIC8vICAgb3BlcmF0aW5nIGluIENpcGhlciBGZWVkYmFjayBtb2RlIHdpdGggc2hpZnQgYW1vdW50IGVxdWFsIHRvIHRoZVxuICAgIC8vICAgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyIChDRkItbiB3aGVyZSBuIGlzIHRoZSBibG9jayBzaXplKS5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cigxKTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpIC8vIFZlcnNpb25cbiAgICArIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzLndyaXRlKClcblxuICAgIHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuICAgIHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtXG4gICAgICAxKVxuXG4gICAgdmFyIHRvaGFzaCA9IGJ5dGVzO1xuXG5cbiAgICAvLyBNb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0LlxuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RDMpO1xuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTQpO1xuXG5cbiAgICB0b2hhc2ggKz0gY3J5cHRvLmhhc2guc2hhMShwcmVmaXggKyB0b2hhc2gpO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChwcmVmaXhyYW5kb20sXG4gICAgICBzZXNzaW9uS2V5QWxnb3JpdGhtLCB0b2hhc2gsIGtleSwgZmFsc2UpLnN1YnN0cmluZygwLFxuICAgICAgcHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBlbmNyeXB0ZWQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBvYmplY3QgcmVhZF9wYWNrZXQgbXVzdFxuICAgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZVxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG4gICAqICAgICAgICAgICAgVGhlIHNlbGVjdGVkIHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byBiZSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgZmFsc2UpO1xuXG5cbiAgICAvLyB0aGVyZSBtdXN0IGJlIGEgbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIHBhY2tldCBhcyB0aGVcbiAgICAvLyBsYXN0IHBhY2tldCBhbmQgZXZlcnl0aGluZyBnZXRzIGhhc2hlZCBleGNlcHQgdGhlIGhhc2ggaXRzZWxmXG4gICAgdGhpcy5oYXNoID0gY3J5cHRvLmhhc2guc2hhMShcbiAgICAgIGNyeXB0by5jZmIubWRjKHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQpICsgZGVjcnlwdGVkLnN1YnN0cmluZygwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjApKTtcblxuXG4gICAgdmFyIG1kYyA9IGRlY3J5cHRlZC5zdWJzdHIoZGVjcnlwdGVkLmxlbmd0aCAtIDIwLCAyMCk7XG5cbiAgICBpZiAodGhpcy5oYXNoICE9IG1kYykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2RpZmljYXRpb24gZGV0ZWN0ZWQuJyk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQuc3Vic3RyKDAsIGRlY3J5cHRlZC5sZW5ndGggLSAyMikpO1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgcGFja2V0L3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkgKi9cblxudmFyIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xOiBBIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldCBob2xkcyB0aGUgc2Vzc2lvbiBrZXlcbiAqIHVzZWQgdG8gZW5jcnlwdCBhIG1lc3NhZ2UuIFplcm8gb3IgbW9yZSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleVxuICogcGFja2V0cyBhbmQvb3IgU3ltbWV0cmljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0cyBtYXkgcHJlY2VkZSBhXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgd2hpY2ggaG9sZHMgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuIFRoZVxuICogbWVzc2FnZSBpcyBlbmNyeXB0ZWQgd2l0aCB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGUgc2Vzc2lvbiBrZXkgaXMgaXRzZWxmXG4gKiBlbmNyeXB0ZWQgYW5kIHN0b3JlZCBpbiB0aGUgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldChzKS4gVGhlXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCBpcyBwcmVjZWRlZCBieSBvbmUgUHVibGljLUtleSBFbmNyeXB0ZWRcbiAqIFNlc3Npb24gS2V5IHBhY2tldCBmb3IgZWFjaCBPcGVuUEdQIGtleSB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBlbmNyeXB0ZWQuXG4gKiBUaGUgcmVjaXBpZW50IG9mIHRoZSBtZXNzYWdlIGZpbmRzIGEgc2Vzc2lvbiBrZXkgdGhhdCBpcyBlbmNyeXB0ZWQgdG8gdGhlaXJcbiAqIHB1YmxpYyBrZXksIGRlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZW4gdXNlcyB0aGUgc2Vzc2lvbiBrZXkgdG9cbiAqIGRlY3J5cHQgdGhlIG1lc3NhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSB7XG4gIHRoaXMudGFnID0gMztcbiAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIHRoaXMuczJrID0gbmV3IHR5cGVfczJrKCk7XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3ltbWV0cmljIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAzKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiBUaGUgb25seSBjdXJyZW50bHkgZGVmaW5lZCB2ZXJzaW9uIGlzIDQuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBzeW1tZXRyaWMgYWxnb3JpdGhtIHVzZWQuXG4gICAgdmFyIGFsZ28gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgYnl0ZXMuY2hhckNvZGVBdCgxKSk7XG5cbiAgICAvLyBBIHN0cmluZy10by1rZXkgKFMySykgc3BlY2lmaWVyLCBsZW5ndGggYXMgZGVmaW5lZCBhYm92ZS5cbiAgICB2YXIgczJrbGVuZ3RoID0gdGhpcy5zMmsucmVhZChieXRlcy5zdWJzdHIoMikpO1xuXG4gICAgLy8gT3B0aW9uYWxseSwgdGhlIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBpdHNlbGYsIHdoaWNoIGlzIGRlY3J5cHRlZFxuICAgIC8vIHdpdGggdGhlIHN0cmluZy10by1rZXkgb2JqZWN0LlxuICAgIHZhciBkb25lID0gczJrbGVuZ3RoICsgMjtcblxuICAgIGlmIChkb25lIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cihkb25lKTtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gPSBhbGdvXG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSBhbGdvO1xuICB9XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhbGdvID0gdGhpcy5lbmNyeXB0ZWQgPT0gbnVsbCA/XG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gOlxuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobTtcblxuICAgIHZhciBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy52ZXJzaW9uKSArXG4gICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgYWxnbykpICtcbiAgICAgIHRoaXMuczJrLndyaXRlKCk7XG5cbiAgICBpZiAodGhpcy5lbmNyeXB0ZWQgIT0gbnVsbClcbiAgICAgIGJ5dGVzICs9IHRoaXMuZW5jcnlwdGVkO1xuICAgIHJldHVybiBieXRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqIHBhY2tldHMgKHRhZyAxKVxuICAgKiBcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICovXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcbiAgICB2YXIgYWxnbyA9IHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gIT0gbnVsbCA/XG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtIDpcbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobTtcblxuXG4gICAgdmFyIGxlbmd0aCA9IGNyeXB0by5jaXBoZXJbYWxnb10ua2V5U2l6ZTtcbiAgICB2YXIga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkocGFzc3BocmFzZSwgbGVuZ3RoKTtcblxuICAgIGlmICh0aGlzLmVuY3J5cHRlZCA9PSBudWxsKSB7XG4gICAgICB0aGlzLnNlc3Npb25LZXkgPSBrZXk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcbiAgICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLFxuICAgICAgICBkZWNyeXB0ZWRbMF0ua2V5Q29kZUF0KCkpO1xuXG4gICAgICB0aGlzLnNlc3Npb25LZXkgPSBkZWNyeXB0ZWQuc3Vic3RyKDEpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcbiAgICB2YXIgbGVuZ3RoID0gY3J5cHRvLmdldEtleUxlbmd0aCh0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtKTtcbiAgICB2YXIga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkocGFzc3BocmFzZSwgbGVuZ3RoKTtcblxuICAgIHZhciBwcml2YXRlX2tleSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpICtcblxuICAgIGNyeXB0by5nZXRSYW5kb21CeXRlcyhcbiAgICAgIGNyeXB0by5nZXRLZXlMZW5ndGgodGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChcbiAgICAgIGNyeXB0by5nZXRQcmVmaXhSYW5kb20odGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSksXG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtLCBrZXksIHByaXZhdGVfa2V5LCB0cnVlKTtcbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIHBhY2tldC9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCAqL1xuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCAoVGFnIDkpXG4gKiBcbiAqIFJGQzQ4ODAgNS43OiBUaGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQgY29udGFpbnMgZGF0YSBlbmNyeXB0ZWRcbiAqIHdpdGggYSBzeW1tZXRyaWMta2V5IGFsZ29yaXRobS4gV2hlbiBpdCBoYXMgYmVlbiBkZWNyeXB0ZWQsIGl0IGNvbnRhaW5zIG90aGVyXG4gKiBwYWNrZXRzICh1c3VhbGx5IGEgbGl0ZXJhbCBkYXRhIHBhY2tldCBvciBjb21wcmVzc2VkIGRhdGEgcGFja2V0LCBidXQgaW5cbiAqIHRoZW9yeSBvdGhlciBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIHBhY2tldHMgb3Igc2VxdWVuY2VzIG9mIHBhY2tldHNcbiAqIHRoYXQgZm9ybSB3aG9sZSBPcGVuUEdQIG1lc3NhZ2VzKS5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCgpIHtcbiAgdGhpcy5lbmNyeXB0ZWQgPSBudWxsO1xuICAvKiogRGVjcnlwdGVkIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbi4gXG4gICAqIEB0eXBlIHttb2R1bGU6cGFja2V0L3BhY2tldGxpc3R9ICovXG4gIHRoaXMucGFja2V0cztcblxuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXM7XG4gIH1cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bW1ldHJpY2FsbHkgZGVjcnlwdCB0aGUgcGFja2V0IGRhdGFcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc2Vzc2lvbktleUFsZ29yaXRobVxuICAgKiAgICAgICAgICAgICBTeW1tZXRyaWMga2V5IGFsZ29yaXRobSB0byB1c2UgLy8gU2VlIFJGQzQ4ODAgOS4yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICogICAgICAgICAgICAgS2V5IGFzIHN0cmluZyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGxlbmd0aCB0byB0aGVcbiAgICogICAgICAgICAgICBhbGdvcml0aG1cbiAgICogQHJldHVybiBUaGUgZGVjcnlwdGVkIGRhdGE7XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYWxnbywga2V5KSB7XG4gICAgdmFyIGRhdGEgPSB0aGlzLnBhY2tldHMud3JpdGUoKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KFxuICAgICAgY3J5cHRvLmdldFByZWZpeFJhbmRvbShhbGdvKSwgYWxnbywgZGF0YSwga2V5LCB0cnVlKTtcbiAgfVxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3RydXN0KCkge1xuXG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgcGFja2V0L3VzZXJfYXR0cmlidXRlICovXG5cbi8qKiBcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBBdHRyaWJ1dGUgUGFja2V0IChUYWcgMTcpXG4gKiAgVGhlIFVzZXIgQXR0cmlidXRlIHBhY2tldCBpcyBhIHZhcmlhdGlvbiBvZiB0aGUgVXNlciBJRCBwYWNrZXQuICBJdFxuICogIGlzIGNhcGFibGUgb2Ygc3RvcmluZyBtb3JlIHR5cGVzIG9mIGRhdGEgdGhhbiB0aGUgVXNlciBJRCBwYWNrZXQsXG4gKiAgd2hpY2ggaXMgbGltaXRlZCB0byB0ZXh0LiAgTGlrZSB0aGUgVXNlciBJRCBwYWNrZXQsIGEgVXNlciBBdHRyaWJ1dGVcbiAqICBwYWNrZXQgbWF5IGJlIGNlcnRpZmllZCBieSB0aGUga2V5IG93bmVyIChcInNlbGYtc2lnbmVkXCIpIG9yIGFueSBvdGhlclxuICogIGtleSBvd25lciB3aG8gY2FyZXMgdG8gY2VydGlmeSBpdC4gIEV4Y2VwdCBhcyBub3RlZCwgYSBVc2VyIEF0dHJpYnV0ZVxuICogIHBhY2tldCBtYXkgYmUgdXNlZCBhbnl3aGVyZSB0aGF0IGEgVXNlciBJRCBwYWNrZXQgbWF5IGJlIHVzZWQuXG4gKlxuICogIFdoaWxlIFVzZXIgQXR0cmlidXRlIHBhY2tldHMgYXJlIG5vdCBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIE9wZW5QR1BcbiAqICBzdGFuZGFyZCwgaW1wbGVtZW50YXRpb25zIFNIT1VMRCBwcm92aWRlIGF0IGxlYXN0IGVub3VnaFxuICogIGNvbXBhdGliaWxpdHkgdG8gcHJvcGVybHkgaGFuZGxlIGEgY2VydGlmaWNhdGlvbiBzaWduYXR1cmUgb24gdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0LiAgQSBzaW1wbGUgd2F5IHRvIGRvIHRoaXMgaXMgYnkgdHJlYXRpbmcgdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGFzIGEgVXNlciBJRCBwYWNrZXQgd2l0aCBvcGFxdWUgY29udGVudHMsIGJ1dFxuICogIGFuIGltcGxlbWVudGF0aW9uIG1heSB1c2UgYW55IG1ldGhvZCBkZXNpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF91c2VyX2F0dHJpYnV0ZSgpIHtcbiAgdGhpcy50YWcgPSAxNztcbiAgdGhpcy5hdHRyaWJ1dGVzID0gW107XG5cbiAgLyoqXG4gICAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgdXNlciBhdHRyaWJ1dGUgcGFja2V0ICh0YWcgMTcpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxNyBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L3VzZXJfYXR0cmlidXRlfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB2YXIgbGVuID0gb3BlbnBncF9wYWNrZXQucmVhZF9zaW1wbGVfbGVuZ3RoKGJ5dGVzKTtcblxuICAgICAgaSArPSBsZW4ub2Zmc2V0O1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzLnB1c2goYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcbiAgICAgIGkgKz0gbGVuLmxlbjtcbiAgICB9XG4gIH1cbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKiogQG1vZHVsZSBwYWNrZXQvdXNlcmlkICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBJRCBQYWNrZXQgKFRhZyAxMylcbiAqIEEgVXNlciBJRCBwYWNrZXQgY29uc2lzdHMgb2YgVVRGLTggdGV4dCB0aGF0IGlzIGludGVuZGVkIHRvIHJlcHJlc2VudFxuICogdGhlIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGtleSBob2xkZXIuICBCeSBjb252ZW50aW9uLCBpdFxuICogaW5jbHVkZXMgYW4gUkZDIDI4MjIgW1JGQzI4MjJdIG1haWwgbmFtZS1hZGRyLCBidXQgdGhlcmUgYXJlIG5vXG4gKiByZXN0cmljdGlvbnMgb24gaXRzIGNvbnRlbnQuICBUaGUgcGFja2V0IGxlbmd0aCBpbiB0aGUgaGVhZGVyXG4gKiBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvZiB0aGUgVXNlciBJRC4gXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJpZCgpIHtcbiAgLyoqIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIgaWQuIFVzdWFsbHkgaW4gdGhlIGZvcm1cbiAgICogSm9obiBEb2UgPGpvaG5AZXhhbXBsZS5jb20+XG4gICAqIEB0eXBlIHtTdHJpbmd9IFxuICAgKi9cbiAgdGhpcy51c2VyaWQgPSAnJztcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHVzZXIgaWQgcGFja2V0ICh0YWcgMTMpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxMyBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBcbiAgICogYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7bW9kdWxlOnBhY2tldC91c2VyaWR9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLnVzZXJpZCA9IHV0aWwuZGVjb2RlX3V0ZjgoYnl0ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVzZXIgaWQgcGFja2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyX2lkIHRoZSB1c2VyIGlkIGFzIHN0cmluZyAoXCJKb2huIERvZSA8am9obi5kb2VAbWFpbC51c1wiKVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMudXNlcmlkKTtcbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgdHlwZS9rZXlpZCAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKVxuICogIEEgS2V5IElEIGlzIGFuIGVpZ2h0LW9jdGV0IHNjYWxhciB0aGF0IGlkZW50aWZpZXMgYSBrZXkuXG4gICBJbXBsZW1lbnRhdGlvbnMgU0hPVUxEIE5PVCBhc3N1bWUgdGhhdCBLZXkgSURzIGFyZSB1bmlxdWUuICBUaGVcbiAgIHNlY3Rpb24gXCJFbmhhbmNlZCBLZXkgRm9ybWF0c1wiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmVcbiAgIGZvcm1lZC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBrZXlpZCgpIHtcblxuICB0aGlzLmJ5dGVzID0gJyc7XG5cblxuICAvKipcbiAgICogUGFyc2luZyBtZXRob2QgZm9yIGEga2V5IGlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCB0byByZWFkIHRoZSBrZXkgaWQgZnJvbSBcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB3aGVyZSB0byBzdGFydCByZWFkaW5nIHRoZSBrZXkgXG4gICAqIGlkIGZyb20gaW5wdXRcbiAgICogQHJldHVybiB7bW9kdWxlOnR5cGUva2V5aWR9IFRoaXMgb2JqZWN0XG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuYnl0ZXMgPSBieXRlcy5zdWJzdHIoMCwgOCk7XG4gIH1cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXM7XG4gIH1cblxuICB0aGlzLnRvSGV4ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHV0aWwuaGV4c3RyZHVtcCh0aGlzLmJ5dGVzKTtcbiAgfVxuXG4gIHRoaXMuZXF1YWxzID0gZnVuY3Rpb24oa2V5aWQpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcyA9PSBrZXlpZC5ieXRlcztcbiAgfVxuXG4gIHRoaXMuaXNOdWxsID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXMgPT09ICcnO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLm1hcFRvSGV4ID0gZnVuY3Rpb24oa2V5SWQpIHtcbiAgcmV0dXJuIGtleUlkLnRvSGV4KCk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vLyBIaW50OiBXZSBob2xkIG91ciBNUElzIGFzIGFuIGFycmF5IG9mIG9jdGV0cyBpbiBiaWcgZW5kaWFuIGZvcm1hdCBwcmVjZWVkaW5nIGEgdHdvXG4vLyBvY3RldCBzY2FsYXI6IE1QSTogW2EsYixjLGQsZSxmXVxuLy8gLSBNUEkgc2l6ZTogKGEgPDwgOCkgfCBiIFxuLy8gLSBNUEkgPSBjIHwgZCA8PCA4IHwgZSA8PCAoKE1QSS5sZW5ndGggLTIpKjgpIHwgZiAoKE1QSS5sZW5ndGggLTIpKjgpXG5cbi8qKiBAbW9kdWxlIHR5cGUvbXBpICovXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi4vY3J5cHRvL3B1YmxpY19rZXkvanNibi5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzY0ltcGxlbWVudGF0aW9uIG9mIHR5cGUgTVBJIChSRkM0ODgwIDMuMilcbiAqIE11bHRpcHJlY2lzaW9uIGludGVnZXJzIChhbHNvIGNhbGxlZCBNUElzKSBhcmUgdW5zaWduZWQgaW50ZWdlcnMgdXNlZFxuICogdG8gaG9sZCBsYXJnZSBpbnRlZ2VycyBzdWNoIGFzIHRoZSBvbmVzIHVzZWQgaW4gY3J5cHRvZ3JhcGhpY1xuICogY2FsY3VsYXRpb25zLlxuICogQW4gTVBJIGNvbnNpc3RzIG9mIHR3byBwaWVjZXM6IGEgdHdvLW9jdGV0IHNjYWxhciB0aGF0IGlzIHRoZSBsZW5ndGhcbiAqIG9mIHRoZSBNUEkgaW4gYml0cyBmb2xsb3dlZCBieSBhIHN0cmluZyBvZiBvY3RldHMgdGhhdCBjb250YWluIHRoZVxuICogYWN0dWFsIGludGVnZXIuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbXBpKCkge1xuICAvKiogQW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IGludGVnZXIgKi9cbiAgdGhpcy5kYXRhID0gbnVsbDtcblxuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBtcGkgKFJGQyA0ODgwIDMuMikuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIG1waSBkYXRhXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBcbiAgICogc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIFxuICAgKiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6dHlwZS9tcGl9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgYml0cyA9IChieXRlcy5jaGFyQ29kZUF0KDApIDw8IDgpIHwgYnl0ZXMuY2hhckNvZGVBdCgxKTtcblxuICAgIC8vIEFkZGl0aW9uYWwgcnVsZXM6XG4gICAgLy9cbiAgICAvLyAgICBUaGUgc2l6ZSBvZiBhbiBNUEkgaXMgKChNUEkubGVuZ3RoICsgNykgLyA4KSArIDIgb2N0ZXRzLlxuICAgIC8vXG4gICAgLy8gICAgVGhlIGxlbmd0aCBmaWVsZCBvZiBhbiBNUEkgZGVzY3JpYmVzIHRoZSBsZW5ndGggc3RhcnRpbmcgZnJvbSBpdHNcbiAgICAvL1x0ICBtb3N0IHNpZ25pZmljYW50IG5vbi16ZXJvIGJpdC4gIFRodXMsIHRoZSBNUEkgWzAwIDAyIDAxXSBpcyBub3RcbiAgICAvLyAgICBmb3JtZWQgY29ycmVjdGx5LiAgSXQgc2hvdWxkIGJlIFswMCAwMSAwMV0uXG5cbiAgICAvLyBUT0RPOiBWZXJpZmljYXRpb24gb2YgdGhpcyBzaXplIG1ldGhvZCEgVGhpcyBzaXplIGNhbGN1bGF0aW9uIGFzXG4gICAgLy8gXHRcdCBzcGVjaWZpZWQgYWJvdmUgaXMgbm90IGFwcGxpY2FibGUgaW4gSmF2YVNjcmlwdFxuICAgIHZhciBieXRlbGVuID0gTWF0aC5jZWlsKGJpdHMgLyA4KTtcblxuICAgIHZhciByYXcgPSBieXRlcy5zdWJzdHIoMiwgYnl0ZWxlbik7XG4gICAgdGhpcy5mcm9tQnl0ZXMocmF3KTtcblxuICAgIHJldHVybiAyICsgYnl0ZWxlbjtcbiAgfVxuXG4gIHRoaXMuZnJvbUJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLmRhdGEgPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoYnl0ZXMpLCAxNik7XG4gIH1cblxuICB0aGlzLnRvQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy53cml0ZSgpLnN1YnN0cigyKTtcbiAgfVxuXG4gIHRoaXMuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvQnl0ZXMoKS5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIG1waSBvYmplY3QgdG8gYSBzdHJpbmcgYXMgc3BlY2lmaWVkIGluIFJGQzQ4ODAgMy4yXG4gICAqIEByZXR1cm4ge1N0cmluZ30gbXBpIEJ5dGUgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLnRvTVBJKCk7XG4gIH1cblxuICB0aGlzLnRvQmlnSW50ZWdlciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEuY2xvbmUoKTtcbiAgfVxuXG4gIHRoaXMuZnJvbUJpZ0ludGVnZXIgPSBmdW5jdGlvbihibikge1xuICAgIHRoaXMuZGF0YSA9IGJuLmNsb25lKCk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBAbW9kdWxlIHR5cGUvczJrICovXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQzQ4ODAgMy43KVxuICogU3RyaW5nLXRvLWtleSAoUzJLKSBzcGVjaWZpZXJzIGFyZSB1c2VkIHRvIGNvbnZlcnQgcGFzc3BocmFzZSBzdHJpbmdzXG4gICBpbnRvIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGtleXMuICBUaGV5IGFyZSB1c2VkIGluIHR3b1xuICAgcGxhY2VzLCBjdXJyZW50bHk6IHRvIGVuY3J5cHQgdGhlIHNlY3JldCBwYXJ0IG9mIHByaXZhdGUga2V5cyBpbiB0aGVcbiAgIHByaXZhdGUga2V5cmluZywgYW5kIHRvIGNvbnZlcnQgcGFzc3BocmFzZXMgdG8gZW5jcnlwdGlvbiBrZXlzIGZvclxuICAgc3ltbWV0cmljYWxseSBlbmNyeXB0ZWQgbWVzc2FnZXMuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gczJrKCkge1xuICAvKiogQHR5cGUge29wZW5wZ3AuaGFzaH0gKi9cbiAgdGhpcy5hbGdvcml0aG0gPSAnc2hhMjU2JztcbiAgLyoqIEB0eXBlIHttb2R1bGU6dHlwZS9zMmt9ICovXG4gIHRoaXMudHlwZSA9ICdpdGVyYXRlZCc7XG4gIHRoaXMuYyA9IDk2O1xuICAvKiogRWlnaHQgYnl0ZXMgb2Ygc2FsdC5cbiAgICogQHR5cGUge29wZW5wZ3BfYnl0ZV9hcnJheX0gXG4gICAqL1xuICB0aGlzLnNhbHQgPSBjcnlwdG8ucmFuZG9tLmdldFJhbmRvbUJ5dGVzKDgpO1xuXG5cbiAgLy8gRXhwb25lbiBiaWFzLCBkZWZpbmVkIGluIFJGQzQ4ODBcbiAgdmFyIGV4cGJpYXMgPSA2O1xuXG4gIHRoaXMuZ2V0X2NvdW50ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuICgxNiArICh0aGlzLmMgJiAxNSkpIDw8ICgodGhpcy5jID4+IDQpICsgZXhwYmlhcyk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBzdHJpbmctdG8ta2V5IHNwZWNpZmllciAoUkZDIDQ4ODAgMy43KS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2Ygc3RyaW5nLXRvLWtleSBzcGVjaWZpZXJcbiAgICogQHJldHVybiB7SW50ZWdlcn0gQWN0dWFsIGxlbmd0aCBvZiB0aGUgb2JqZWN0XG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcbiAgICB0aGlzLnR5cGUgPSBlbnVtcy5yZWFkKGVudW1zLnMyaywgYnl0ZXMuY2hhckNvZGVBdChpKyspKTtcbiAgICB0aGlzLmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuaGFzaCwgYnl0ZXMuY2hhckNvZGVBdChpKyspKTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgdGhpcy5zYWx0ID0gYnl0ZXMuc3Vic3RyKGksIDgpO1xuICAgICAgICBpICs9IDg7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdpdGVyYXRlZCc6XG4gICAgICAgIHRoaXMuc2FsdCA9IGJ5dGVzLnN1YnN0cihpLCA4KTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9jdGV0IDEwOiBjb3VudCwgYSBvbmUtb2N0ZXQsIGNvZGVkIHZhbHVlXG4gICAgICAgIHRoaXMuYyA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2dudSc6XG4gICAgICAgIGlmIChieXRlcy5zdWJzdHIoaSwgMykgPT0gXCJHTlVcIikge1xuICAgICAgICAgIGkgKz0gMzsgLy8gR05VXG4gICAgICAgICAgdmFyIGdudUV4dFR5cGUgPSAxMDAwICsgYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICAgIGlmIChnbnVFeHRUeXBlID09IDEwMDEpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IGdudUV4dFR5cGU7XG4gICAgICAgICAgICAvLyBHbnVQRyBleHRlbnNpb24gbW9kZSAxMDAxIC0tIGRvbid0IHdyaXRlIHNlY3JldCBrZXkgYXQgYWxsXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIGdudSBwcm90ZWN0aW9uIG1vZGUuXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayB0eXBlLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzMmsgdHlwZS5cIik7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBpO1xuICB9XG5cblxuICAvKipcbiAgICogd3JpdGVzIGFuIHMyayBoYXNoIGJhc2VkIG9uIHRoZSBpbnB1dHMuXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IG9mIGhhc2hBbGdvcml0aG0gaGFzaCBsZW5ndGhcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnMyaywgdGhpcy50eXBlKSk7XG4gICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmFsZ29yaXRobSkpO1xuXG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgYnl0ZXMgKz0gdGhpcy5zYWx0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgYnl0ZXMgKz0gdGhpcy5zYWx0O1xuICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuYyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH07XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBrZXkgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXNzcGhyYXNlIGFuZCB0aGUgZGVmaW5lZCBcbiAgICogaGFzaEFsZ29yaXRobSBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2UgUGFzc3BocmFzZSBjb250YWluaW5nIHVzZXIgaW5wdXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBQcm9kdWNlZCBrZXkgd2l0aCBhIGxlbmd0aCBjb3JyZXNwb25kaW5nIHRvIFxuICAgKiBoYXNoQWxnb3JpdGhtIGhhc2ggbGVuZ3RoXG4gICAqL1xuICB0aGlzLnByb2R1Y2Vfa2V5ID0gZnVuY3Rpb24ocGFzc3BocmFzZSwgbnVtQnl0ZXMpIHtcbiAgICBwYXNzcGhyYXNlID0gdXRpbC5lbmNvZGVfdXRmOChwYXNzcGhyYXNlKTtcblxuICAgIGZ1bmN0aW9uIHJvdW5kKHByZWZpeCwgczJrKSB7XG4gICAgICB2YXIgYWxnb3JpdGhtID0gZW51bXMud3JpdGUoZW51bXMuaGFzaCwgczJrLmFsZ29yaXRobSk7XG5cbiAgICAgIHN3aXRjaCAoczJrLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2ltcGxlJzpcbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgcGFzc3BocmFzZSk7XG5cbiAgICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSxcbiAgICAgICAgICAgIHByZWZpeCArIHMyay5zYWx0ICsgcGFzc3BocmFzZSk7XG5cbiAgICAgICAgY2FzZSAnaXRlcmF0ZWQnOlxuICAgICAgICAgIHZhciBpc3AgPSBbXSxcbiAgICAgICAgICAgIGNvdW50ID0gczJrLmdldF9jb3VudCgpO1xuICAgICAgICAgIGRhdGEgPSBzMmsuc2FsdCArIHBhc3NwaHJhc2U7XG5cbiAgICAgICAgICB3aGlsZSAoaXNwLmxlbmd0aCAqIGRhdGEubGVuZ3RoIDwgY291bnQpXG4gICAgICAgICAgICBpc3AucHVzaChkYXRhKTtcblxuICAgICAgICAgIGlzcCA9IGlzcC5qb2luKCcnKTtcblxuICAgICAgICAgIGlmIChpc3AubGVuZ3RoID4gY291bnQpXG4gICAgICAgICAgICBpc3AgPSBpc3Auc3Vic3RyKDAsIGNvdW50KTtcblxuICAgICAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5kaWdlc3QoYWxnb3JpdGhtLCBwcmVmaXggKyBpc3ApO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0ID0gJycsXG4gICAgICBwcmVmaXggPSAnJztcblxuICAgIHdoaWxlIChyZXN1bHQubGVuZ3RoIDw9IG51bUJ5dGVzKSB7XG4gICAgICByZXN1bHQgKz0gcm91bmQocHJlZml4LCB0aGlzKTtcbiAgICAgIHByZWZpeCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQuc3Vic3RyKDAsIG51bUJ5dGVzKTtcbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqIEBtb2R1bGUgdXRpbC91dGlsICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuLyoqXG4gKlxuICogVGhpcyBvYmplY3QgY29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnNcbiAqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIHV0aWwgb2JqZWN0XG4gKi9cbnZhciBVdGlsID0gZnVuY3Rpb24oKSB7XG5cbiAgdGhpcy5yZWFkTnVtYmVyID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbiA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBuIDw8PSA4O1xuICAgICAgbiArPSBieXRlcy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIHJldHVybiBuO1xuICB9O1xuXG4gIHRoaXMud3JpdGVOdW1iZXIgPSBmdW5jdGlvbihuLCBieXRlcykge1xuICAgIHZhciBiID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlczsgaSsrKSB7XG4gICAgICBiICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKG4gPj4gKDggKiAoYnl0ZXMgLSBpIC0gMSkpKSAmIDB4RkYpO1xuICAgIH1cblxuICAgIHJldHVybiBiO1xuICB9O1xuXG5cblxuICB0aGlzLnJlYWREYXRlID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbiA9IHRoaXMucmVhZE51bWJlcihieXRlcyk7XG4gICAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICAgIGQuc2V0VGltZShuICogMTAwMCk7XG4gICAgcmV0dXJuIGQ7XG4gIH07XG5cbiAgdGhpcy53cml0ZURhdGUgPSBmdW5jdGlvbih0aW1lKSB7XG4gICAgdmFyIG51bWVyaWMgPSBNYXRoLnJvdW5kKHRpbWUuZ2V0VGltZSgpIC8gMTAwMCk7XG5cbiAgICByZXR1cm4gdGhpcy53cml0ZU51bWJlcihudW1lcmljLCA0KTtcbiAgfTtcblxuICB0aGlzLmVtYWlsUmVnRXggPSAvXlsrYS16QS1aMC05Xy4tXStAKFthLXpBLVowLTktXStcXC4pK1thLXpBLVowLTldezIsNn0kLztcblxuICB0aGlzLmRlYnVnID0gZmFsc2U7XG5cbiAgdGhpcy5oZXhkdW1wID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHIgPSBbXTtcbiAgICB2YXIgZSA9IHN0ci5sZW5ndGg7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBoO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoYyA8IGUpIHtcbiAgICAgIGggPSBzdHIuY2hhckNvZGVBdChjKyspLnRvU3RyaW5nKDE2KTtcbiAgICAgIHdoaWxlIChoLmxlbmd0aCA8IDIpIGggPSBcIjBcIiArIGg7XG4gICAgICByLnB1c2goXCIgXCIgKyBoKTtcbiAgICAgIGkrKztcbiAgICAgIGlmIChpICUgMzIgPT0gMClcbiAgICAgICAgci5wdXNoKFwiXFxuICAgICAgICAgICBcIik7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgaGV4c3RyaW5nIGZyb20gYSBiaW5hcnlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBjb250YWluaW5nIHRoZSBoZXhhZGVjaW1hbCB2YWx1ZXNcbiAgICovXG4gIHRoaXMuaGV4c3RyZHVtcCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIGlmIChzdHIgPT0gbnVsbClcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIHZhciByID0gW107XG4gICAgdmFyIGUgPSBzdHIubGVuZ3RoO1xuICAgIHZhciBjID0gMDtcbiAgICB2YXIgaDtcbiAgICB3aGlsZSAoYyA8IGUpIHtcbiAgICAgIGggPSBzdHIuY2hhckNvZGVBdChjKyspLnRvU3RyaW5nKDE2KTtcbiAgICAgIHdoaWxlIChoLmxlbmd0aCA8IDIpIGggPSBcIjBcIiArIGg7XG4gICAgICByLnB1c2goXCJcIiArIGgpO1xuICAgIH1cbiAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGJpbmFyeSBzdHJpbmcgZnJvbSBhIGhleCBlbmNvZGVkIHN0cmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEhleCBzdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBjb250YWluaW5nIHRoZSBiaW5hcnkgdmFsdWVzXG4gICAqL1xuICB0aGlzLmhleDJiaW4gPSBmdW5jdGlvbihoZXgpIHtcbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpXG4gICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNikpO1xuICAgIHJldHVybiBzdHI7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0aW5nIGEgaGV4IHN0cmluZyBmcm9tIGFuIGJpbmFyeSBhcnJheSBvZiBpbnRlZ2VycyAoMC4uMjU1KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEFycmF5IG9mIGJ5dGVzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBIZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuaGV4aWR1bXAgPSBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyW2MrK10udG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIlwiICsgaCk7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcgdG8gYSBzdHJpbmcgb2YgdXRmOCBieXRlc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgdmFsaWQgc3F1ZW5jZSBvZiB1dGY4IGJ5dGVzXG4gICAqL1xuICB0aGlzLmVuY29kZV91dGY4ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKTtcbiAgfTtcblxuICAvKipcbiAgICogQ29udmVydCBhIHN0cmluZyBvZiB1dGY4IGJ5dGVzIHRvIGEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1dGY4IEEgdmFsaWQgc3F1ZW5jZSBvZiB1dGY4IGJ5dGVzXG4gICAqIEByZXR1cm4ge1N0cmluZ30gQSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICovXG4gIHRoaXMuZGVjb2RlX3V0ZjggPSBmdW5jdGlvbih1dGY4KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHV0ZjgpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gdXRmODtcbiAgICB9XG4gIH07XG5cbiAgdmFyIHN0cjJiaW4gPSBmdW5jdGlvbihzdHIsIHJlc3VsdCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHRbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIHZhciBiaW4yc3RyID0gZnVuY3Rpb24oYmluKSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiaW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmluW2ldKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTtcbiAgfTtcblxuICAvKipcbiAgICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBpbnRlZ2VycygwLjI1NSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtBcnJheTxJbnRlZ2VyPn0gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnNcbiAgICovXG4gIHRoaXMuc3RyMmJpbiA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHJldHVybiBzdHIyYmluKHN0ciwgbmV3IEFycmF5KHN0ci5sZW5ndGgpKTtcbiAgfTtcblxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KSB0byBhIHN0cmluZyBcbiAgICogQHBhcmFtIHtBcnJheTxJbnRlZ2VyPn0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgdGhpcy5iaW4yc3RyID0gYmluMnN0cjtcblxuICAvKipcbiAgICogQ29udmVydCBhIHN0cmluZyB0byBhIFVpbnQ4QXJyYXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fSBUaGUgYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnNcbiAgICovXG4gIHRoaXMuc3RyMlVpbnQ4QXJyYXkgPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyMmJpbihzdHIsIG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihzdHIubGVuZ3RoKSkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgVWludDhBcnJheSB0byBhIHN0cmluZy4gVGhpcyBjdXJyZW50bHkgZnVuY3Rpb25zIFxuICAgKiB0aGUgc2FtZSBhcyBiaW4yc3RyLiBcbiAgICogQHBhcmFtIHtVaW50OEFycmF5fSBiaW4gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnMgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuVWludDhBcnJheTJzdHIgPSBiaW4yc3RyO1xuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIGEgMTZiaXQgc3VtIG9mIGEgc3RyaW5nIGJ5IGFkZGluZyBlYWNoIGNoYXJhY3RlciBcbiAgICogY29kZXMgbW9kdWx1cyA2NTUzNVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBTdHJpbmcgdG8gY3JlYXRlIGEgc3VtIG9mXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IEFuIGludGVnZXIgY29udGFpbmluZyB0aGUgc3VtIG9mIGFsbCBjaGFyYWN0ZXIgXG4gICAqIGNvZGVzICUgNjU1MzVcbiAgICovXG4gIHRoaXMuY2FsY19jaGVja3N1bSA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgICB2YXIgY2hlY2tzdW0gPSB7XG4gICAgICBzOiAwLFxuICAgICAgYWRkOiBmdW5jdGlvbihzYWRkKSB7XG4gICAgICAgIHRoaXMucyA9ICh0aGlzLnMgKyBzYWRkKSAlIDY1NTM2O1xuICAgICAgfVxuICAgIH07XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGVja3N1bS5hZGQodGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNoZWNrc3VtLnM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhIGRlYnVnIG1lc3NhZ2UuIERlYnVnIFxuICAgKiBtZXNzYWdlcyBhcmUgb25seSBwcmludGVkIGlmXG4gICAqIG9wZW5wZ3AuY29uZmlnLmRlYnVnIGlzIHNldCB0byB0cnVlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyBvZiB0aGUgZGVidWcgbWVzc2FnZVxuICAgKi9cbiAgdGhpcy5wcmludF9kZWJ1ZyA9IGZ1bmN0aW9uKHN0cikge1xuICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlLiBEZWJ1ZyBcbiAgICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZlxuICAgKiBvcGVucGdwLmNvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS5cbiAgICogRGlmZmVyZW50IHRoYW4gcHJpbnRfZGVidWcgYmVjYXVzZSB3aWxsIGNhbGwgaGV4c3RyZHVtcCBpZmYgbmVjZXNzYXJ5LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyBvZiB0aGUgZGVidWcgbWVzc2FnZVxuICAgKi9cbiAgdGhpcy5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcCA9IGZ1bmN0aW9uKHN0ciwgc3RyVG9IZXgpIHtcbiAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICBzdHIgPSBzdHIgKyB0aGlzLmhleHN0cmR1bXAoc3RyVG9IZXgpO1xuICAgICAgY29uc29sZS5sb2coc3RyKTtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5nZXRMZWZ0TkJpdHMgPSBmdW5jdGlvbihzdHJpbmcsIGJpdGNvdW50KSB7XG4gICAgdmFyIHJlc3QgPSBiaXRjb3VudCAlIDg7XG4gICAgaWYgKHJlc3QgPT0gMClcbiAgICAgIHJldHVybiBzdHJpbmcuc3Vic3RyaW5nKDAsIGJpdGNvdW50IC8gOCk7XG4gICAgdmFyIGJ5dGVzID0gKGJpdGNvdW50IC0gcmVzdCkgLyA4ICsgMTtcbiAgICB2YXIgcmVzdWx0ID0gc3RyaW5nLnN1YnN0cmluZygwLCBieXRlcyk7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRSaWdodChyZXN1bHQsIDggLSByZXN0KTsgLy8gK1N0cmluZy5mcm9tQ2hhckNvZGUoc3RyaW5nLmNoYXJDb2RlQXQoYnl0ZXMgLTEpIDw8ICg4LXJlc3QpICYgMHhGRik7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNoaWZ0aW5nIGEgc3RyaW5nIHRvIG4gYml0cyByaWdodFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVGhlIHN0cmluZyB0byBzaGlmdFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGJpdGNvdW50IEFtb3VudCBvZiBiaXRzIHRvIHNoaWZ0IChNVVNUIGJlIHNtYWxsZXIgXG4gICAqIHRoYW4gOSlcbiAgICogQHJldHVybiB7U3RyaW5nfSBSZXN1bHRpbmcgc3RyaW5nLiBcbiAgICovXG4gIHRoaXMuc2hpZnRSaWdodCA9IGZ1bmN0aW9uKHZhbHVlLCBiaXRjb3VudCkge1xuICAgIHZhciB0ZW1wID0gdXRpbC5zdHIyYmluKHZhbHVlKTtcbiAgICBpZiAoYml0Y291bnQgJSA4ICE9IDApIHtcbiAgICAgIGZvciAodmFyIGkgPSB0ZW1wLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRlbXBbaV0gPj49IGJpdGNvdW50ICUgODtcbiAgICAgICAgaWYgKGkgPiAwKVxuICAgICAgICAgIHRlbXBbaV0gfD0gKHRlbXBbaSAtIDFdIDw8ICg4IC0gKGJpdGNvdW50ICUgOCkpKSAmIDB4RkY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHV0aWwuYmluMnN0cih0ZW1wKTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBhbGdvcml0aG0gdHlwZSBhcyBzdHJpbmdcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBtZXNzYWdlIHR5cGVcbiAgICovXG4gIHRoaXMuZ2V0X2hhc2hBbGdvcml0aG1TdHJpbmcgPSBmdW5jdGlvbihhbGdvKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiBcIk1ENVwiO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gXCJTSEExXCI7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiBcIlJJUEVNRDE2MFwiO1xuICAgICAgY2FzZSA4OlxuICAgICAgICByZXR1cm4gXCJTSEEyNTZcIjtcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgcmV0dXJuIFwiU0hBMzg0XCI7XG4gICAgICBjYXNlIDEwOlxuICAgICAgICByZXR1cm4gXCJTSEE1MTJcIjtcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIHJldHVybiBcIlNIQTIyNFwiO1xuICAgIH1cbiAgICByZXR1cm4gXCJ1bmtub3duXCI7XG4gIH07XG5cbn07XG5cbi8qKlxuICogYW4gaW5zdGFuY2UgdGhhdCBzaG91bGQgYmUgdXNlZC4gXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVXRpbCgpO1xuIl19 +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NsZWFydGV4dC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY29tcHJlc3Npb24vanhnLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jb25maWcvY29uZmlnLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2ZiLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vY2lwaGVyL2Flcy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9ibG93ZmlzaC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NpcGhlci9kZXMuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9jaXBoZXIvdHdvZmlzaC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2NyeXB0by5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9oYXNoL21kNS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvcmlwZS1tZC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL2hhc2gvc2hhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2NyeXB0by9wa2NzMS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvZHNhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9lbGdhbWFsLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcHVibGljX2tleS9pbmRleC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvanNibi5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvcnNhLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vcmFuZG9tLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9jcnlwdG8vc2lnbmF0dXJlLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9lbmNvZGluZy9hcm1vci5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvZW5jb2RpbmcvYmFzZTY0LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9lbnVtcy5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvaW5kZXguanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL2tleS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvbWVzc2FnZS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvb3BlbnBncC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2FsbF9wYWNrZXRzLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvY29tcHJlc3NlZC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L2luZGV4LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvbGl0ZXJhbC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L21hcmtlci5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L29uZV9wYXNzX3NpZ25hdHVyZS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3BhY2tldC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3BhY2tldGxpc3QuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfa2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9wdWJsaWNfc3Via2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc2VjcmV0X2tleS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3NlY3JldF9zdWJrZXkuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zaWduYXR1cmUuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3BhY2tldC90cnVzdC5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvcGFja2V0L3VzZXJfYXR0cmlidXRlLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy9wYWNrZXQvdXNlcmlkLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL2tleWlkLmpzIiwiL2hvbWUvcm9iZXJ0L3ppbWJyYS1wZ3Avb3BlbnBncGpzLWRldmVsL3NyYy90eXBlL21waS5qcyIsIi9ob21lL3JvYmVydC96aW1icmEtcGdwL29wZW5wZ3Bqcy1kZXZlbC9zcmMvdHlwZS9zMmsuanMiLCIvaG9tZS9yb2JlcnQvemltYnJhLXBncC9vcGVucGdwanMtZGV2ZWwvc3JjL3V0aWwvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbnZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hhQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3paQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNybUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzl2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaG9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQHJlcXVpcmVzIGNvbmZpZ1xuICogQHJlcXVpcmVzIGVuY29kaW5nL2FybW9yXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyBwYWNrZXRcbiAqIEBtb2R1bGUgY2xlYXJ0ZXh0XG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyksXG4gIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0JyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpLFxuICBhcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIE9wZW5QR1AgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlLlxuICogU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi03XG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgICB0ZXh0ICAgICAgIFRoZSBjbGVhcnRleHQgb2YgdGhlIHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3BhY2tldGxpc3R9IHBhY2tldGxpc3QgVGhlIHBhY2tldGxpc3Qgd2l0aCBzaWduYXR1cmUgcGFja2V0cyBvciB1bmRlZmluZWRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbWVzc2FnZSBub3QgeWV0IHNpZ25lZFxuICovXG5cbmZ1bmN0aW9uIENsZWFydGV4dE1lc3NhZ2UodGV4dCwgcGFja2V0bGlzdCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ2xlYXJ0ZXh0TWVzc2FnZSkpIHtcbiAgICByZXR1cm4gbmV3IENsZWFydGV4dE1lc3NhZ2UocGFja2V0bGlzdCk7XG4gIH1cbiAgLy8gbm9ybWFsaXplIEVPTCB0byBjYW5vbmljYWwgZm9ybSA8Q1I+PExGPlxuICB0aGlzLnRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcci9nLCAnJykucmVwbGFjZSgvW1xcdCBdK1xcbi9nLCBcIlxcblwiKS5yZXBsYWNlKC9cXG4vZyxcIlxcclxcblwiKTtcbiAgdGhpcy5wYWNrZXRzID0gcGFja2V0bGlzdCB8fCBuZXcgcGFja2V0Lmxpc3QoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRoYXQgc2lnbmVkIHRoZSBjbGVhcnRleHQgbWVzc2FnZVxuICogQHJldHVybiB7QXJyYXk8bW9kdWxlOnR5cGUva2V5aWQ+fSBhcnJheSBvZiBrZXlpZCBvYmplY3RzXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLmdldFNpZ25pbmdLZXlJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGtleUlkcyA9IFtdO1xuICB2YXIgc2lnbmF0dXJlTGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuc2lnbmF0dXJlKTtcbiAgc2lnbmF0dXJlTGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgIGtleUlkcy5wdXNoKHBhY2tldC5pc3N1ZXJLZXlJZCk7XG4gIH0pO1xuICByZXR1cm4ga2V5SWRzO1xufTtcblxuLyoqXG4gKiBTaWduIHRoZSBjbGVhcnRleHQgbWVzc2FnZVxuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSBwcml2YXRlS2V5cyBwcml2YXRlIGtleXMgd2l0aCBkZWNyeXB0ZWQgc2VjcmV0IGtleSBkYXRhIGZvciBzaWduaW5nXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbihwcml2YXRlS2V5cykge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpOyAgXG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IG5ldyBwYWNrZXQubGl0ZXJhbCgpO1xuICBsaXRlcmFsRGF0YVBhY2tldC5zZXRUZXh0KHRoaXMudGV4dCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJpdmF0ZUtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgICBzaWduYXR1cmVQYWNrZXQuc2lnbmF0dXJlVHlwZSA9IGVudW1zLnNpZ25hdHVyZS50ZXh0O1xuICAgIHNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbiAgICB2YXIgc2lnbmluZ0tleVBhY2tldCA9IHByaXZhdGVLZXlzW2ldLmdldFNpZ25pbmdLZXlQYWNrZXQoKTtcbiAgICBzaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgaWYgKCFzaWduaW5nS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gICAgc2lnbmF0dXJlUGFja2V0LnNpZ24oc2lnbmluZ0tleVBhY2tldCwgbGl0ZXJhbERhdGFQYWNrZXQpO1xuICAgIHBhY2tldGxpc3QucHVzaChzaWduYXR1cmVQYWNrZXQpO1xuICB9XG4gIHRoaXMucGFja2V0cyA9IHBhY2tldGxpc3Q7XG59O1xuXG4vKipcbiAqIFZlcmlmeSBzaWduYXR1cmVzIG9mIGNsZWFydGV4dCBzaWduZWQgbWVzc2FnZVxuICogQHBhcmFtIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHB1YmxpY0tleXMgcHVibGljIGtleXMgdG8gdmVyaWZ5IHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge0FycmF5PHtrZXlpZDogbW9kdWxlOnR5cGUva2V5aWQsIHZhbGlkOiBCb29sZWFufT59IGxpc3Qgb2Ygc2lnbmVyJ3Mga2V5aWQgYW5kIHZhbGlkaXR5IG9mIHNpZ25hdHVyZVxuICovXG5DbGVhcnRleHRNZXNzYWdlLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbihwdWJsaWNLZXlzKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIHNpZ25hdHVyZUxpc3QgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNpZ25hdHVyZSk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldCA9IG5ldyBwYWNrZXQubGl0ZXJhbCgpO1xuICAvLyB3ZSBhc3N1bWUgdGhhdCBjbGVhcnRleHQgc2lnbmF0dXJlIGlzIGdlbmVyYXRlZCBiYXNlZCBvbiBVVEY4IGNsZWFydGV4dFxuICBsaXRlcmFsRGF0YVBhY2tldC5zZXRUZXh0KHRoaXMudGV4dCk7XG4gIHB1YmxpY0tleXMuZm9yRWFjaChmdW5jdGlvbihwdWJLZXkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ25hdHVyZUxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwdWJsaWNLZXlQYWNrZXQgPSBwdWJLZXkuZ2V0UHVibGljS2V5UGFja2V0KFtzaWduYXR1cmVMaXN0W2ldLmlzc3VlcktleUlkXSk7XG4gICAgICBpZiAocHVibGljS2V5UGFja2V0KSB7XG4gICAgICAgIHZhciB2ZXJpZmllZFNpZyA9IHt9O1xuICAgICAgICB2ZXJpZmllZFNpZy5rZXlpZCA9IHNpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWQ7XG4gICAgICAgIHZlcmlmaWVkU2lnLnZhbGlkID0gc2lnbmF0dXJlTGlzdFtpXS52ZXJpZnkocHVibGljS2V5UGFja2V0LCBsaXRlcmFsRGF0YVBhY2tldCk7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZlcmlmaWVkU2lnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogR2V0IGNsZWFydGV4dFxuICogQHJldHVybiB7U3RyaW5nfSBjbGVhcnRleHQgb2YgbWVzc2FnZVxuICovXG5DbGVhcnRleHRNZXNzYWdlLnByb3RvdHlwZS5nZXRUZXh0ID0gZnVuY3Rpb24oKSB7XG4gIC8vIG5vcm1hbGl6ZSBlbmQgb2YgbGluZSB0byBcXG5cbiAgcmV0dXJuIHRoaXMudGV4dC5yZXBsYWNlKC9cXHJcXG4vZyxcIlxcblwiKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBBU0NJSSBhcm1vcmVkIHRleHQgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcmV0dXJuIHtTdHJpbmd9IEFTQ0lJIGFybW9yXG4gKi9cbkNsZWFydGV4dE1lc3NhZ2UucHJvdG90eXBlLmFybW9yID0gZnVuY3Rpb24oKSB7XG4gIHZhciBib2R5ID0ge1xuICAgIGhhc2g6IGVudW1zLnJlYWQoZW51bXMuaGFzaCwgY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobSkudG9VcHBlckNhc2UoKSxcbiAgICB0ZXh0OiB0aGlzLnRleHQsXG4gICAgZGF0YTogdGhpcy5wYWNrZXRzLndyaXRlKClcbiAgfVxuICByZXR1cm4gYXJtb3IuZW5jb2RlKGVudW1zLmFybW9yLnNpZ25lZCwgYm9keSk7XG59O1xuXG5cbi8qKlxuICogcmVhZHMgYW4gT3BlblBHUCBjbGVhcnRleHQgc2lnbmVkIG1lc3NhZ2UgYW5kIHJldHVybnMgYSBDbGVhcnRleHRNZXNzYWdlIG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWRUZXh0IHRleHQgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJuIHttb2R1bGU6Y2xlYXJ0ZXh0fkNsZWFydGV4dE1lc3NhZ2V9IG5ldyBjbGVhcnRleHQgbWVzc2FnZSBvYmplY3RcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KTtcbiAgaWYgKGlucHV0LnR5cGUgIT09IGVudW1zLmFybW9yLnNpZ25lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlLicpO1xuICB9XG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gIHBhY2tldGxpc3QucmVhZChpbnB1dC5kYXRhKTtcbiAgdmFyIG5ld01lc3NhZ2UgPSBuZXcgQ2xlYXJ0ZXh0TWVzc2FnZShpbnB1dC50ZXh0LCBwYWNrZXRsaXN0KTtcbiAgcmV0dXJuIG5ld01lc3NhZ2U7XG59XG5cbmV4cG9ydHMuQ2xlYXJ0ZXh0TWVzc2FnZSA9IENsZWFydGV4dE1lc3NhZ2U7XG5leHBvcnRzLnJlYWRBcm1vcmVkID0gcmVhZEFybW9yZWQ7XG4iLCJKWEcgPSB7XG4gIGV4aXN0czogKGZ1bmN0aW9uKHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBmdW5jdGlvbih2KSB7XG4gICAgICByZXR1cm4gISh2ID09PSB1bmRlZmluZWQgfHwgdiA9PT0gbnVsbCk7XG4gICAgfVxuICB9KSgpXG59O1xuSlhHLmRlY29tcHJlc3MgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIHVuZXNjYXBlKChuZXcgSlhHLlV0aWwuVW56aXAoSlhHLlV0aWwuQmFzZTY0LmRlY29kZUFzQXJyYXkoc3RyKSkpLnVuemlwKClbMF1bMF0pO1xufTtcbi8qXG4gICAgQ29weXJpZ2h0IDIwMDgtMjAxMlxuICAgICAgICBNYXR0aGlhcyBFaG1hbm4sXG4gICAgICAgIE1pY2hhZWwgR2VyaGFldXNlcixcbiAgICAgICAgQ2Fyc3RlbiBNaWxsZXIsXG4gICAgICAgIEJpYW5jYSBWYWxlbnRpbixcbiAgICAgICAgQWxmcmVkIFdhc3Nlcm1hbm4sXG4gICAgICAgIFBldGVyIFdpbGZhaHJ0XG5cbiAgICBUaGlzIGZpbGUgaXMgcGFydCBvZiBKU1hHcmFwaC5cbiAgICBcbiAgICBEdWFsIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgb3IgTEdQTCBWZXJzaW9uIDMgbGljZW5zZXMuXG5cbiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAgICBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gICAgXG4gICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgQXBhY2hlIExpY2Vuc2UgYWxvbmcgd2l0aCBKU1hDb21wcmVzc29yLiAgXG4gICAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8+LlxuXG4qL1xuXG4vKipcbiAqIEBjbGFzcyBVdGlsIGNsYXNzXG4gKiBAY2xhc3NkZXNjIFV0aWxpdGllcyBmb3IgdW5jb21wcmVzc2luZyBhbmQgYmFzZTY0IGRlY29kaW5nXG4gKiBDbGFzcyBmb3IgZ3VuemlwcGluZywgdW56aXBwaW5nIGFuZCBiYXNlNjQgZGVjb2Rpbmcgb2YgZmlsZXMuXG4gKiBJdCBpcyB1c2VkIGZvciByZWFkaW5nIEdFT05FeFQsIEdlb2dlYnJhIGFuZCBJbnRlcmdlbyBmaWxlcy5cbiAqXG4gKiBPbmx5IEh1ZmZtYW4gY29kZXMgYXJlIGRlY29kZWQgaW4gZ3VuemlwLlxuICogVGhlIGNvZGUgaXMgYmFzZWQgb24gdGhlIHNvdXJjZSBjb2RlIGZvciBndW56aXAuYyBieSBQYXNpIE9qYWxhIFxuICoge0BsaW5rIGh0dHA6Ly93d3cuY3MudHV0LmZpL35hbGJlcnQvRGV2L2d1bnppcC9ndW56aXAuY31cbiAqIHtAbGluayBodHRwOi8vd3d3LmNzLnR1dC5maS9+YWxiZXJ0fVxuICovXG5KWEcuVXRpbCA9IHt9O1xuXG4vKipcbiAqIFVuemlwIHppcCBmaWxlc1xuICovXG5KWEcuVXRpbC5VbnppcCA9IGZ1bmN0aW9uKGJhcnJheSkge1xuICB2YXIgb3V0cHV0QXJyID0gW10sXG4gICAgb3V0cHV0ID0gXCJcIixcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIGdwZmxhZ3MsXG4gICAgZmlsZXMgPSAwLFxuICAgIHVuemlwcGVkID0gW10sXG4gICAgY3JjLFxuICAgIGJ1ZjMyayA9IG5ldyBBcnJheSgzMjc2OCksXG4gICAgYklkeCA9IDAsXG4gICAgbW9kZVpJUCA9IGZhbHNlLFxuXG4gICAgQ1JDLCBTSVpFLFxuXG4gICAgYml0UmV2ZXJzZSA9IFtcbiAgICAgICAgMHgwMCwgMHg4MCwgMHg0MCwgMHhjMCwgMHgyMCwgMHhhMCwgMHg2MCwgMHhlMCxcbiAgICAgICAgMHgxMCwgMHg5MCwgMHg1MCwgMHhkMCwgMHgzMCwgMHhiMCwgMHg3MCwgMHhmMCxcbiAgICAgICAgMHgwOCwgMHg4OCwgMHg0OCwgMHhjOCwgMHgyOCwgMHhhOCwgMHg2OCwgMHhlOCxcbiAgICAgICAgMHgxOCwgMHg5OCwgMHg1OCwgMHhkOCwgMHgzOCwgMHhiOCwgMHg3OCwgMHhmOCxcbiAgICAgICAgMHgwNCwgMHg4NCwgMHg0NCwgMHhjNCwgMHgyNCwgMHhhNCwgMHg2NCwgMHhlNCxcbiAgICAgICAgMHgxNCwgMHg5NCwgMHg1NCwgMHhkNCwgMHgzNCwgMHhiNCwgMHg3NCwgMHhmNCxcbiAgICAgICAgMHgwYywgMHg4YywgMHg0YywgMHhjYywgMHgyYywgMHhhYywgMHg2YywgMHhlYyxcbiAgICAgICAgMHgxYywgMHg5YywgMHg1YywgMHhkYywgMHgzYywgMHhiYywgMHg3YywgMHhmYyxcbiAgICAgICAgMHgwMiwgMHg4MiwgMHg0MiwgMHhjMiwgMHgyMiwgMHhhMiwgMHg2MiwgMHhlMixcbiAgICAgICAgMHgxMiwgMHg5MiwgMHg1MiwgMHhkMiwgMHgzMiwgMHhiMiwgMHg3MiwgMHhmMixcbiAgICAgICAgMHgwYSwgMHg4YSwgMHg0YSwgMHhjYSwgMHgyYSwgMHhhYSwgMHg2YSwgMHhlYSxcbiAgICAgICAgMHgxYSwgMHg5YSwgMHg1YSwgMHhkYSwgMHgzYSwgMHhiYSwgMHg3YSwgMHhmYSxcbiAgICAgICAgMHgwNiwgMHg4NiwgMHg0NiwgMHhjNiwgMHgyNiwgMHhhNiwgMHg2NiwgMHhlNixcbiAgICAgICAgMHgxNiwgMHg5NiwgMHg1NiwgMHhkNiwgMHgzNiwgMHhiNiwgMHg3NiwgMHhmNixcbiAgICAgICAgMHgwZSwgMHg4ZSwgMHg0ZSwgMHhjZSwgMHgyZSwgMHhhZSwgMHg2ZSwgMHhlZSxcbiAgICAgICAgMHgxZSwgMHg5ZSwgMHg1ZSwgMHhkZSwgMHgzZSwgMHhiZSwgMHg3ZSwgMHhmZSxcbiAgICAgICAgMHgwMSwgMHg4MSwgMHg0MSwgMHhjMSwgMHgyMSwgMHhhMSwgMHg2MSwgMHhlMSxcbiAgICAgICAgMHgxMSwgMHg5MSwgMHg1MSwgMHhkMSwgMHgzMSwgMHhiMSwgMHg3MSwgMHhmMSxcbiAgICAgICAgMHgwOSwgMHg4OSwgMHg0OSwgMHhjOSwgMHgyOSwgMHhhOSwgMHg2OSwgMHhlOSxcbiAgICAgICAgMHgxOSwgMHg5OSwgMHg1OSwgMHhkOSwgMHgzOSwgMHhiOSwgMHg3OSwgMHhmOSxcbiAgICAgICAgMHgwNSwgMHg4NSwgMHg0NSwgMHhjNSwgMHgyNSwgMHhhNSwgMHg2NSwgMHhlNSxcbiAgICAgICAgMHgxNSwgMHg5NSwgMHg1NSwgMHhkNSwgMHgzNSwgMHhiNSwgMHg3NSwgMHhmNSxcbiAgICAgICAgMHgwZCwgMHg4ZCwgMHg0ZCwgMHhjZCwgMHgyZCwgMHhhZCwgMHg2ZCwgMHhlZCxcbiAgICAgICAgMHgxZCwgMHg5ZCwgMHg1ZCwgMHhkZCwgMHgzZCwgMHhiZCwgMHg3ZCwgMHhmZCxcbiAgICAgICAgMHgwMywgMHg4MywgMHg0MywgMHhjMywgMHgyMywgMHhhMywgMHg2MywgMHhlMyxcbiAgICAgICAgMHgxMywgMHg5MywgMHg1MywgMHhkMywgMHgzMywgMHhiMywgMHg3MywgMHhmMyxcbiAgICAgICAgMHgwYiwgMHg4YiwgMHg0YiwgMHhjYiwgMHgyYiwgMHhhYiwgMHg2YiwgMHhlYixcbiAgICAgICAgMHgxYiwgMHg5YiwgMHg1YiwgMHhkYiwgMHgzYiwgMHhiYiwgMHg3YiwgMHhmYixcbiAgICAgICAgMHgwNywgMHg4NywgMHg0NywgMHhjNywgMHgyNywgMHhhNywgMHg2NywgMHhlNyxcbiAgICAgICAgMHgxNywgMHg5NywgMHg1NywgMHhkNywgMHgzNywgMHhiNywgMHg3NywgMHhmNyxcbiAgICAgICAgMHgwZiwgMHg4ZiwgMHg0ZiwgMHhjZiwgMHgyZiwgMHhhZiwgMHg2ZiwgMHhlZixcbiAgICAgICAgMHgxZiwgMHg5ZiwgMHg1ZiwgMHhkZiwgMHgzZiwgMHhiZiwgMHg3ZiwgMHhmZlxuICAgIF0sXG5cbiAgICBjcGxlbnMgPSBbXG4gICAgICAgIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTMsIDE1LCAxNywgMTksIDIzLCAyNywgMzEsXG4gICAgICAgIDM1LCA0MywgNTEsIDU5LCA2NywgODMsIDk5LCAxMTUsIDEzMSwgMTYzLCAxOTUsIDIyNywgMjU4LCAwLCAwXG4gICAgXSxcblxuICAgIGNwbGV4dCA9IFtcbiAgICAgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMiwgMiwgMiwgMixcbiAgICAgICAgMywgMywgMywgMywgNCwgNCwgNCwgNCwgNSwgNSwgNSwgNSwgMCwgOTksIDk5XG4gICAgXSxcbiAgICAvKiA5OT09aW52YWxpZCAqL1xuXG4gICAgY3BkaXN0ID0gW1xuICAgICAgICAweDAwMDEsIDB4MDAwMiwgMHgwMDAzLCAweDAwMDQsIDB4MDAwNSwgMHgwMDA3LCAweDAwMDksIDB4MDAwZCxcbiAgICAgICAgMHgwMDExLCAweDAwMTksIDB4MDAyMSwgMHgwMDMxLCAweDAwNDEsIDB4MDA2MSwgMHgwMDgxLCAweDAwYzEsXG4gICAgICAgIDB4MDEwMSwgMHgwMTgxLCAweDAyMDEsIDB4MDMwMSwgMHgwNDAxLCAweDA2MDEsIDB4MDgwMSwgMHgwYzAxLFxuICAgICAgICAweDEwMDEsIDB4MTgwMSwgMHgyMDAxLCAweDMwMDEsIDB4NDAwMSwgMHg2MDAxXG4gICAgXSxcblxuICAgIGNwZGV4dCA9IFtcbiAgICAgICAgMCwgMCwgMCwgMCwgMSwgMSwgMiwgMixcbiAgICAgICAgMywgMywgNCwgNCwgNSwgNSwgNiwgNixcbiAgICAgICAgNywgNywgOCwgOCwgOSwgOSwgMTAsIDEwLFxuICAgICAgICAxMSwgMTEsIDEyLCAxMiwgMTMsIDEzXG4gICAgXSxcblxuICAgIGJvcmRlciA9IFsxNiwgMTcsIDE4LCAwLCA4LCA3LCA5LCA2LCAxMCwgNSwgMTEsIDQsIDEyLCAzLCAxMywgMiwgMTQsIDEsIDE1XSxcblxuICAgIGJBID0gYmFycmF5LFxuXG4gICAgYnl0ZXBvcyA9IDAsXG4gICAgYml0cG9zID0gMCxcbiAgICBiYiA9IDEsXG4gICAgYml0cyA9IDAsXG5cbiAgICBOQU1FTUFYID0gMjU2LFxuXG4gICAgbmFtZUJ1ZiA9IFtdLFxuXG4gICAgZmlsZW91dDtcblxuICBmdW5jdGlvbiByZWFkQnl0ZSgpIHtcbiAgICBiaXRzICs9IDg7XG4gICAgaWYgKGJ5dGVwb3MgPCBiQS5sZW5ndGgpIHtcbiAgICAgIC8vaWYgKGRlYnVnKVxuICAgICAgLy8gICAgZG9jdW1lbnQud3JpdGUoYnl0ZXBvcytcIjogXCIrYkFbYnl0ZXBvc10rXCI8YnI+XCIpO1xuICAgICAgcmV0dXJuIGJBW2J5dGVwb3MrK107XG4gICAgfSBlbHNlXG4gICAgICByZXR1cm4gLTE7XG4gIH07XG5cbiAgZnVuY3Rpb24gYnl0ZUFsaWduKCkge1xuICAgIGJiID0gMTtcbiAgfTtcblxuICBmdW5jdGlvbiByZWFkQml0KCkge1xuICAgIHZhciBjYXJyeTtcbiAgICBiaXRzKys7XG4gICAgY2FycnkgPSAoYmIgJiAxKTtcbiAgICBiYiA+Pj0gMTtcbiAgICBpZiAoYmIgPT0gMCkge1xuICAgICAgYmIgPSByZWFkQnl0ZSgpO1xuICAgICAgY2FycnkgPSAoYmIgJiAxKTtcbiAgICAgIGJiID0gKGJiID4+IDEpIHwgMHg4MDtcbiAgICB9XG4gICAgcmV0dXJuIGNhcnJ5O1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlYWRCaXRzKGEpIHtcbiAgICB2YXIgcmVzID0gMCxcbiAgICAgIGkgPSBhO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcmVzID0gKHJlcyA8PCAxKSB8IHJlYWRCaXQoKTtcbiAgICB9XG4gICAgaWYgKGEpIHtcbiAgICAgIHJlcyA9IGJpdFJldmVyc2VbcmVzXSA+PiAoOCAtIGEpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGZsdXNoQnVmZmVyKCkge1xuICAgIC8vZG9jdW1lbnQud3JpdGUoJ0ZMVVNIQlVGRkVSOicrYnVmMzJrKTtcbiAgICBiSWR4ID0gMDtcbiAgfTtcblxuICBmdW5jdGlvbiBhZGRCdWZmZXIoYSkge1xuICAgIFNJWkUrKztcbiAgICAvL0NSQz11cGRjcmMoYSxjcmMpO1xuICAgIGJ1ZjMya1tiSWR4KytdID0gYTtcbiAgICBvdXRwdXRBcnIucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGEpKTtcbiAgICAvL291dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShhKTtcbiAgICBpZiAoYklkeCA9PSAweDgwMDApIHtcbiAgICAgIC8vZG9jdW1lbnQud3JpdGUoJ0FEREJVRkZFUjonK2J1ZjMyayk7XG4gICAgICBiSWR4ID0gMDtcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gSHVmTm9kZSgpIHtcbiAgICB0aGlzLmIwID0gMDtcbiAgICB0aGlzLmIxID0gMDtcbiAgICB0aGlzLmp1bXAgPSBudWxsO1xuICAgIHRoaXMuanVtcHBvcyA9IC0xO1xuICB9O1xuXG4gIHZhciBMSVRFUkFMUyA9IDI4ODtcblxuICB2YXIgbGl0ZXJhbFRyZWUgPSBuZXcgQXJyYXkoTElURVJBTFMpO1xuICB2YXIgZGlzdGFuY2VUcmVlID0gbmV3IEFycmF5KDMyKTtcbiAgdmFyIHRyZWVwb3MgPSAwO1xuICB2YXIgUGxhY2VzID0gbnVsbDtcbiAgdmFyIFBsYWNlczIgPSBudWxsO1xuXG4gIHZhciBpbXBEaXN0YW5jZVRyZWUgPSBuZXcgQXJyYXkoNjQpO1xuICB2YXIgaW1wTGVuZ3RoVHJlZSA9IG5ldyBBcnJheSg2NCk7XG5cbiAgdmFyIGxlbiA9IDA7XG4gIHZhciBmcG9zID0gbmV3IEFycmF5KDE3KTtcbiAgZnBvc1swXSA9IDA7XG4gIHZhciBmbGVucztcbiAgdmFyIGZtYXg7XG5cbiAgZnVuY3Rpb24gSXNQYXQoKSB7XG4gICAgd2hpbGUgKDEpIHtcbiAgICAgIGlmIChmcG9zW2xlbl0gPj0gZm1heClcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgaWYgKGZsZW5zW2Zwb3NbbGVuXV0gPT0gbGVuKVxuICAgICAgICByZXR1cm4gZnBvc1tsZW5dKys7XG4gICAgICBmcG9zW2xlbl0rKztcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gUmVjKCkge1xuICAgIHZhciBjdXJwbGFjZSA9IFBsYWNlc1t0cmVlcG9zXTtcbiAgICB2YXIgdG1wO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmxlbjpcIiArIGxlbiArIFwiIHRyZWVwb3M6XCIgKyB0cmVlcG9zKTtcbiAgICBpZiAobGVuID09IDE3KSB7IC8vd2FyIDE3XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHRyZWVwb3MrKztcbiAgICBsZW4rKztcblxuICAgIHRtcCA9IElzUGF0KCk7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+SXNQYXQgXCIgKyB0bXApO1xuICAgIGlmICh0bXAgPj0gMCkge1xuICAgICAgY3VycGxhY2UuYjAgPSB0bXA7IC8qIGxlYWYgY2VsbCBmb3IgMC1iaXQgKi9cbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjAgXCIgKyBjdXJwbGFjZS5iMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vdCBhIExlYWYgY2VsbCAqL1xuICAgICAgY3VycGxhY2UuYjAgPSAweDgwMDA7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIwIFwiICsgY3VycGxhY2UuYjApO1xuICAgICAgaWYgKFJlYygpKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHRtcCA9IElzUGF0KCk7XG4gICAgaWYgKHRtcCA+PSAwKSB7XG4gICAgICBjdXJwbGFjZS5iMSA9IHRtcDsgLyogbGVhZiBjZWxsIGZvciAxLWJpdCAqL1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMSBcIiArIGN1cnBsYWNlLmIxKTtcbiAgICAgIGN1cnBsYWNlLmp1bXAgPSBudWxsOyAvKiBKdXN0IGZvciB0aGUgZGlzcGxheSByb3V0aW5lICovXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vdCBhIExlYWYgY2VsbCAqL1xuICAgICAgY3VycGxhY2UuYjEgPSAweDgwMDA7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIxIFwiICsgY3VycGxhY2UuYjEpO1xuICAgICAgY3VycGxhY2UuanVtcCA9IFBsYWNlc1t0cmVlcG9zXTtcbiAgICAgIGN1cnBsYWNlLmp1bXBwb3MgPSB0cmVlcG9zO1xuICAgICAgaWYgKFJlYygpKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGxlbi0tO1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIENyZWF0ZVRyZWUoY3VycmVudFRyZWUsIG51bXZhbCwgbGVuZ3Rocywgc2hvdykge1xuICAgIHZhciBpO1xuICAgIC8qIENyZWF0ZSB0aGUgSHVmZm1hbiBkZWNvZGUgdHJlZS90YWJsZSAqL1xuICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+Y3JlYXRldHJlZTxicj5cIik7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgZG9jdW1lbnQud3JpdGUoXCJjdXJyZW50VHJlZSBcIiArIGN1cnJlbnRUcmVlICsgXCIgbnVtdmFsIFwiICsgbnVtdmFsICsgXCIgbGVuZ3RocyBcIiArIGxlbmd0aHMgKyBcIiBzaG93IFwiICsgc2hvdyk7XG4gICAgUGxhY2VzID0gY3VycmVudFRyZWU7XG4gICAgdHJlZXBvcyA9IDA7XG4gICAgZmxlbnMgPSBsZW5ndGhzO1xuICAgIGZtYXggPSBudW12YWw7XG4gICAgZm9yIChpID0gMDsgaSA8IDE3OyBpKyspXG4gICAgICBmcG9zW2ldID0gMDtcbiAgICBsZW4gPSAwO1xuICAgIGlmIChSZWMoKSkge1xuICAgICAgLy9mcHJpbnRmKHN0ZGVyciwgXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBkb2N1bWVudC53cml0ZSgnPGJyPlRyZWU6ICcgKyBQbGFjZXMubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGEgPSAwOyBhIDwgMzI7IGErKykge1xuICAgICAgICBkb2N1bWVudC53cml0ZShcIlBsYWNlc1tcIiArIGEgKyBcIl0uYjA9XCIgKyBQbGFjZXNbYV0uYjAgKyBcIjxicj5cIik7XG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiUGxhY2VzW1wiICsgYSArIFwiXS5iMT1cIiArIFBsYWNlc1thXS5iMSArIFwiPGJyPlwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKmlmKHNob3cpIHtcbiAgICAgICAgICAgIHZhciB0bXA7XG4gICAgICAgICAgICBmb3IodG1wPWN1cnJlbnRUcmVlO3RtcDxQbGFjZXM7dG1wKyspIHtcbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIweCUwM3ggIDB4JTAzeCAoMHglMDR4KVwiLHRtcC1jdXJyZW50VHJlZSwgdG1wLT5qdW1wP3RtcC0+anVtcC1jdXJyZW50VHJlZTowLCh0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjApKjYrMHhjZjApO1xuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIwICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICAvL2ZwcmludGYoc3Rkb3V0LCBcIiAgMHglMDN4ICglYylcIiwgdG1wLT5iMCwodG1wLT5iMDwyNTYgJiYgaXNwcmludCh0bXAtPmIwKSk/dG1wLT5iMDon77+9Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIxICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICBpZigodG1wLmIwICYgMHg4MDAwKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIiAgICAgICAgICAgXCIpO1xuICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIgIDB4JTAzeCAoJWMpXCIsIHRtcC0+YjEsKHRtcC0+YjE8MjU2ICYmIGlzcHJpbnQodG1wLT5iMSkpP3RtcC0+YjE6J++/vScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0qL1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIGZ1bmN0aW9uIERlY29kZVZhbHVlKGN1cnJlbnRUcmVlKSB7XG4gICAgdmFyIGxlbiwgaSxcbiAgICAgIHh0cmVlcG9zID0gMCxcbiAgICAgIFggPSBjdXJyZW50VHJlZVt4dHJlZXBvc10sXG4gICAgICBiO1xuXG4gICAgLyogZGVjb2RlIG9uZSBzeW1ib2wgb2YgdGhlIGRhdGEgKi9cbiAgICB3aGlsZSAoMSkge1xuICAgICAgYiA9IHJlYWRCaXQoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJiPVwiICsgYik7XG4gICAgICBpZiAoYikge1xuICAgICAgICBpZiAoIShYLmIxICYgMHg4MDAwKSkge1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwicmV0MVwiKTtcbiAgICAgICAgICByZXR1cm4gWC5iMTsgLyogSWYgbGVhZiBub2RlLCByZXR1cm4gZGF0YSAqL1xuICAgICAgICB9XG4gICAgICAgIFggPSBYLmp1bXA7XG4gICAgICAgIGxlbiA9IGN1cnJlbnRUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRUcmVlW2ldID09PSBYKSB7XG4gICAgICAgICAgICB4dHJlZXBvcyA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy94dHJlZXBvcysrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCEoWC5iMCAmIDB4ODAwMCkpIHtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcInJldDJcIik7XG4gICAgICAgICAgcmV0dXJuIFguYjA7IC8qIElmIGxlYWYgbm9kZSwgcmV0dXJuIGRhdGEgKi9cbiAgICAgICAgfVxuICAgICAgICAvL1grKzsgLy8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9cbiAgICAgICAgeHRyZWVwb3MrKztcbiAgICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gRGVmbGF0ZUxvb3AoKSB7XG4gICAgdmFyIGxhc3QsIGMsIHR5cGUsIGksIGxlbjtcblxuICAgIGRvIHtcbiAgICAgIC8qaWYoKGxhc3QgPSByZWFkQml0KCkpKXtcbiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsIFwiTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJOb3QgTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9Ki9cbiAgICAgIGxhc3QgPSByZWFkQml0KCk7XG4gICAgICB0eXBlID0gcmVhZEJpdHMoMik7XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiU3RvcmVkXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJGaXhlZCBIdWZmbWFuIGNvZGVzXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJEeW5hbWljIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlJlc2VydmVkIGJsb2NrIHR5cGUhIVxcblwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlVuZXhwZWN0ZWQgdmFsdWUgJWQhXFxuXCIsIHR5cGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PSAwKSB7XG4gICAgICAgIHZhciBibG9ja0xlbiwgY1N1bTtcblxuICAgICAgICAvLyBTdG9yZWQgXG4gICAgICAgIGJ5dGVBbGlnbigpO1xuICAgICAgICBibG9ja0xlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGJsb2NrTGVuIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGNTdW0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBjU3VtIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGlmICgoKGJsb2NrTGVuIF4gfmNTdW0pICYgMHhmZmZmKSkge1xuICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiQmxvY2tMZW4gY2hlY2tzdW0gbWlzbWF0Y2hcXG5cIik7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJsb2NrTGVuLS0pIHtcbiAgICAgICAgICBjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSAxKSB7XG4gICAgICAgIHZhciBqO1xuXG4gICAgICAgIC8qIEZpeGVkIEh1ZmZtYW4gdGFibGVzIC0tIGZpeGVkIGRlY29kZSByb3V0aW5lICovXG4gICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAyNTYgICAgMDAwMDAwMCAgICAgICAgMFxuICAgICAgICAgICAgICAgIDogICA6ICAgICA6XG4gICAgICAgICAgICAgICAgMjc5ICAgIDAwMTAxMTEgICAgICAgIDIzXG4gICAgICAgICAgICAgICAgMCAgIDAwMTEwMDAwICAgIDQ4XG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDE0MyAgICAxMDExMTExMSAgICAxOTFcbiAgICAgICAgICAgICAgICAyODAgMTEwMDAwMDAgICAgMTkyXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDI4NyAxMTAwMDExMSAgICAxOTlcbiAgICAgICAgICAgICAgICAxNDQgICAgMTEwMDEwMDAwICAgIDQwMFxuICAgICAgICAgICAgICAgIDogICAgOiAgICAgICA6XG4gICAgICAgICAgICAgICAgMjU1ICAgIDExMTExMTExMSAgICA1MTFcbiAgICBcbiAgICAgICAgICAgICAgICBOb3RlIHRoZSBiaXQgb3JkZXIhXG4gICAgICAgICAgICAgICAgKi9cblxuICAgICAgICAgIGogPSAoYml0UmV2ZXJzZVtyZWFkQml0cyg3KV0gPj4gMSk7XG4gICAgICAgICAgaWYgKGogPiAyMykge1xuICAgICAgICAgICAgaiA9IChqIDw8IDEpIHwgcmVhZEJpdCgpOyAvKiA0OC4uMjU1ICovXG5cbiAgICAgICAgICAgIGlmIChqID4gMTk5KSB7IC8qIDIwMC4uMjU1ICovXG4gICAgICAgICAgICAgIGogLT0gMTI4OyAvKiAgNzIuLjEyNyAqL1xuICAgICAgICAgICAgICBqID0gKGogPDwgMSkgfCByZWFkQml0KCk7IC8qIDE0NC4uMjU1IDw8ICovXG4gICAgICAgICAgICB9IGVsc2UgeyAvKiAgNDguLjE5OSAqL1xuICAgICAgICAgICAgICBqIC09IDQ4OyAvKiAgIDAuLjE1MSAqL1xuICAgICAgICAgICAgICBpZiAoaiA+IDE0Mykge1xuICAgICAgICAgICAgICAgIGogPSBqICsgMTM2OyAvKiAyODAuLjI4NyA8PCAqL1xuICAgICAgICAgICAgICAgIC8qICAgMC4uMTQzIDw8ICovXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgeyAvKiAgIDAuLjIzICovXG4gICAgICAgICAgICBqICs9IDI1NjsgLyogMjU2Li4yNzkgPDwgKi9cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCAyNTYpIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCJvdXQ6XCIrU3RyaW5nLmZyb21DaGFyQ29kZShqKSk7XG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkICUwMnhcXG5cIiwgU0laRSwgaik7Ki9cbiAgICAgICAgICB9IGVsc2UgaWYgKGogPT0gMjU2KSB7XG4gICAgICAgICAgICAvKiBFT0YgKi9cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuXG4gICAgICAgICAgICBqIC09IDI1NiArIDE7IC8qIGJ5dGVzICsgRU9GICovXG4gICAgICAgICAgICBsZW4gPSByZWFkQml0cyhjcGxleHRbal0pICsgY3BsZW5zW2pdO1xuXG4gICAgICAgICAgICBqID0gYml0UmV2ZXJzZVtyZWFkQml0cyg1KV0gPj4gMztcbiAgICAgICAgICAgIGlmIChjcGRleHRbal0gPiA4KSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTtcbiAgICAgICAgICAgICAgZGlzdCB8PSAocmVhZEJpdHMoY3BkZXh0W2pdIC0gOCkgPDwgOCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gY3BkaXN0W2pdO1xuXG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkIChsJTAyeCxkJTA0eClcXG5cIiwgU0laRSwgbGVuLCBkaXN0KTsqL1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIHdoaWxlXG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gMikge1xuICAgICAgICB2YXIgaiwgbiwgbGl0ZXJhbENvZGVzLCBkaXN0Q29kZXMsIGxlbkNvZGVzO1xuICAgICAgICB2YXIgbGwgPSBuZXcgQXJyYXkoMjg4ICsgMzIpOyAvLyBcInN0YXRpY1wiIGp1c3QgdG8gcHJlc2VydmUgc3RhY2tcblxuICAgICAgICAvLyBEeW5hbWljIEh1ZmZtYW4gdGFibGVzIFxuXG4gICAgICAgIGxpdGVyYWxDb2RlcyA9IDI1NyArIHJlYWRCaXRzKDUpO1xuICAgICAgICBkaXN0Q29kZXMgPSAxICsgcmVhZEJpdHMoNSk7XG4gICAgICAgIGxlbkNvZGVzID0gNCArIHJlYWRCaXRzKDQpO1xuICAgICAgICAvL2RvY3VtZW50LndyaXRlKFwiPGJyPnBhcmFtOiBcIitsaXRlcmFsQ29kZXMrXCIgXCIrZGlzdENvZGVzK1wiIFwiK2xlbkNvZGVzK1wiPGJyPlwiKTtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IDE5OyBqKyspIHtcbiAgICAgICAgICBsbFtqXSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIGRlY29kZSB0cmVlIGNvZGUgbGVuZ3Roc1xuXG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGVuQ29kZXM7IGorKykge1xuICAgICAgICAgIGxsW2JvcmRlcltqXV0gPSByZWFkQml0cygzKTtcbiAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKGxsW2JvcmRlcltqXV0rXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxicj5sbDonK2xsKTtcbiAgICAgICAgbGVuID0gZGlzdGFuY2VUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGRpc3RhbmNlVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgMTksIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+ZGlzdGFuY2VUcmVlXCIpO1xuICAgICAgICAgIGZvciAodmFyIGEgPSAwOyBhIDwgZGlzdGFuY2VUcmVlLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIGRpc3RhbmNlVHJlZVthXS5iMCArIFwiIFwiICsgZGlzdGFuY2VUcmVlW2FdLmIxICsgXCIgXCIgKyBkaXN0YW5jZVRyZWVbYV0uanVtcCArIFwiIFwiICtcbiAgICAgICAgICAgICAgZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MpO1xuICAgICAgICAgICAgLyppZiAoZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MhPS0xKVxuICAgICAgICAgICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIwK1wiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIxKTtcbiAgICAgICAgICAgICAgICBcdCovXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxCUj50cmVlIGNyZWF0ZWQnKTtcblxuICAgICAgICAvL3JlYWQgaW4gbGl0ZXJhbCBhbmQgZGlzdGFuY2UgY29kZSBsZW5ndGhzXG4gICAgICAgIG4gPSBsaXRlcmFsQ29kZXMgKyBkaXN0Q29kZXM7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICB2YXIgeiA9IC0xO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bj1cIiArIG4gKyBcIiBiaXRzOiBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgICAgIHorKztcbiAgICAgICAgICBqID0gRGVjb2RlVmFsdWUoZGlzdGFuY2VUcmVlKTtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIHogKyBcIiBpOlwiICsgaSArIFwiIGRlY29kZTogXCIgKyBqICsgXCIgICAgYml0cyBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgICAgaWYgKGogPCAxNikgeyAvLyBsZW5ndGggb2YgY29kZSBpbiBiaXRzICgwLi4xNSlcbiAgICAgICAgICAgIGxsW2krK10gPSBqO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaiA9PSAxNikgeyAvLyByZXBlYXQgbGFzdCBsZW5ndGggMyB0byA2IHRpbWVzIFxuICAgICAgICAgICAgdmFyIGw7XG4gICAgICAgICAgICBqID0gMyArIHJlYWRCaXRzKDIpO1xuICAgICAgICAgICAgaWYgKGkgKyBqID4gbikge1xuICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGwgPSBpID8gbGxbaSAtIDFdIDogMDtcbiAgICAgICAgICAgIHdoaWxlIChqLS0pIHtcbiAgICAgICAgICAgICAgbGxbaSsrXSA9IGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChqID09IDE3KSB7IC8vIDMgdG8gMTAgemVybyBsZW5ndGggY29kZXNcbiAgICAgICAgICAgICAgaiA9IDMgKyByZWFkQml0cygzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGogPT0gMTg6IDExIHRvIDEzOCB6ZXJvIGxlbmd0aCBjb2RlcyBcbiAgICAgICAgICAgICAgaiA9IDExICsgcmVhZEJpdHMoNyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaSArIGogPiBuKSB7XG4gICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICAgICAgICBsbFtpKytdID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypmb3Ioaj0wOyBqPGxpdGVyYWxDb2RlcytkaXN0Q29kZXM7IGorKykge1xuICAgICAgICAgICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCIlZCBcIiwgbGxbal0pO1xuICAgICAgICAgICAgICAgIGlmICgoaiY3KT09NylcbiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTsqL1xuICAgICAgICAvLyBDYW4gb3ZlcndyaXRlIHRyZWUgZGVjb2RlIHRyZWUgYXMgaXQgaXMgbm90IHVzZWQgYW55bW9yZVxuICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBsaXRlcmFsVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGxpdGVyYWxUcmVlLCBsaXRlcmFsQ29kZXMsIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgbGVuID0gbGl0ZXJhbFRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgZGlzdGFuY2VUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgdmFyIGxsMiA9IG5ldyBBcnJheSgpO1xuICAgICAgICBmb3IgKGkgPSBsaXRlcmFsQ29kZXM7IGkgPCBsbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGxsMltpIC0gbGl0ZXJhbENvZGVzXSA9IGxsW2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgZGlzdENvZGVzLCBsbDIsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bGl0ZXJhbFRyZWVcIik7XG4gICAgICAgIG91dGVyOiB3aGlsZSAoMSkge1xuICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShsaXRlcmFsVHJlZSk7XG4gICAgICAgICAgaWYgKGogPj0gMjU2KSB7IC8vIEluIEM2NDogaWYgY2Fycnkgc2V0XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuICAgICAgICAgICAgaiAtPSAyNTY7XG4gICAgICAgICAgICBpZiAoaiA9PSAwKSB7XG4gICAgICAgICAgICAgIC8vIEVPRlxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGotLTtcbiAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07XG5cbiAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgICAgaWYgKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKDgpO1xuICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0gLSA4KSA8PCA4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyhjcGRleHRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG4gICAgICAgICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgICAgICAgaWYgKGJJZHggLSBkaXN0IDwgMCkge1xuICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICghbGFzdCk7XG4gICAgZmx1c2hCdWZmZXIoKTtcblxuICAgIGJ5dGVBbGlnbigpO1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcEZpbGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIGk7XG4gICAgdGhpcy51bnppcCgpO1xuICAgIC8vYWxlcnQodW56aXBwZWRbMF1bMV0pO1xuICAgIGZvciAoaSA9IDA7IGkgPCB1bnppcHBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHVuemlwcGVkW2ldWzFdID09IG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHVuemlwcGVkW2ldWzBdO1xuICAgICAgfVxuICAgIH1cblxuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS5kZWZsYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgb3V0cHV0QXJyID0gW107XG4gICAgdmFyIHRtcCA9IFtdO1xuICAgIG1vZGVaSVAgPSBmYWxzZTtcbiAgICBEZWZsYXRlTG9vcCgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcIkRFRkxBVEVcIjtcbiAgICBmaWxlcysrO1xuICAgIHJldHVybiB1bnppcHBlZDtcbiAgfVxuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcCA9IGZ1bmN0aW9uKCkge1xuICAgIC8vY29udmVydFRvQnl0ZUFycmF5KGlucHV0KTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChiQSk7XG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aCo4O2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJpdCgpKTtcblx0XHRpZiAoKGkrMSklOD09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiIFwiKTtcblx0fSovXG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aDtpKyspe1xuXHRcdGRvY3VtZW50LndyaXRlKHJlYWRCeXRlKCkrXCIgXCIpO1xuXHRcdGlmICgoaSsxKSU4PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIpO1xuXHR9XG5cdGZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUoYkFbaV0rXCIgXCIpO1xuXHRcdGlmICgoaSsxKSUxNj09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiPGJyPlwiKTtcblx0fVx0XG5cdCovXG4gICAgLy9hbGVydChiQSk7XG4gICAgbmV4dEZpbGUoKTtcbiAgICByZXR1cm4gdW56aXBwZWQ7XG4gIH07XG5cbiAgZnVuY3Rpb24gbmV4dEZpbGUoKSB7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgYWxlcnQoXCJORVhURklMRVwiKTtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChcInR5cGU6IFwiICsgdG1wWzBdICsgXCIgXCIgKyB0bXBbMV0pO1xuICAgIGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLCAxNikgJiYgdG1wWzFdID09IHBhcnNlSW50KFwiZGFcIiwgMTYpKSB7IC8vR1pJUFxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkdFT05FeFQtR1pJUFwiKTtcbiAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcImdlb25leHQuZ3h0XCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNzhcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjljXCIsIDE2KSkgeyAvL1pMSUJcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJaTElCXCIpO1xuICAgICAgRGVmbGF0ZUxvb3AoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiWkxJQlwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjFmXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI4YlwiLCAxNikpIHsgLy9HWklQXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiR1pJUFwiKTtcbiAgICAgIC8vRGVmbGF0ZUxvb3AoKTtcbiAgICAgIHNraXBkaXIoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiZmlsZVwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjUwXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLCAxNikpIHsgLy9aSVBcbiAgICAgIG1vZGVaSVAgPSB0cnVlO1xuICAgICAgdG1wWzJdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFszXSA9IHJlYWRCeXRlKCk7XG4gICAgICBpZiAodG1wWzJdID09IHBhcnNlSW50KFwiM1wiLCAxNikgJiYgdG1wWzNdID09IHBhcnNlSW50KFwiNFwiLCAxNikpIHtcbiAgICAgICAgLy9NT0RFX1pJUFxuICAgICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgICB0bXBbMV0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJaSVAtVmVyc2lvbjogXCIgKyB0bXBbMV0gKyBcIiBcIiArIHRtcFswXSAvIDEwICsgXCIuXCIgKyB0bXBbMF0gJSAxMCk7XG5cbiAgICAgICAgZ3BmbGFncyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGdwZmxhZ3MgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcImdwZmxhZ3M6IFwiICsgZ3BmbGFncyk7XG5cbiAgICAgICAgdmFyIG1ldGhvZCA9IHJlYWRCeXRlKCk7XG4gICAgICAgIG1ldGhvZCB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwibWV0aG9kOiBcIiArIG1ldGhvZCk7XG5cbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcblxuICAgICAgICB2YXIgY3JjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIHZhciBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICB2YXIgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJsb2NhbCBDUkM6IFwiICsgY3JjICsgXCJcXG5sb2NhbCBTaXplOiBcIiArIHNpemUgKyBcIlxcbmxvY2FsIENvbXBTaXplOiBcIiArIGNvbXBTaXplKTtcblxuICAgICAgICB2YXIgZmlsZWxlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGZpbGVsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgdmFyIGV4dHJhbGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZXh0cmFsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwiZmlsZWxlbiBcIiArIGZpbGVsZW4pO1xuICAgICAgICBpID0gMDtcbiAgICAgICAgbmFtZUJ1ZiA9IFtdO1xuICAgICAgICB3aGlsZSAoZmlsZWxlbi0tKSB7XG4gICAgICAgICAgdmFyIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGlmIChjID09IFwiL1wiIHwgYyA9PSBcIjpcIikge1xuICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgfSBlbHNlIGlmIChpIDwgTkFNRU1BWCAtIDEpXG4gICAgICAgICAgICBuYW1lQnVmW2krK10gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcIm5hbWVCdWY6IFwiICsgbmFtZUJ1Zik7XG5cbiAgICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgICAgaWYgKCFmaWxlb3V0KVxuICAgICAgICAgIGZpbGVvdXQgPSBuYW1lQnVmO1xuXG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBleHRyYWxlbikge1xuICAgICAgICAgIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuXG4gICAgICAgIENSQyA9IDB4ZmZmZmZmZmY7XG4gICAgICAgIFNJWkUgPSAwO1xuXG4gICAgICAgIGlmIChzaXplID09IDAgJiYgZmlsZU91dC5jaGFyQXQoZmlsZW91dC5sZW5ndGggLSAxKSA9PSBcIi9cIikge1xuICAgICAgICAgIC8vc2tpcGRpclxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwic2tpcGRpclwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0aG9kID09IDgpIHtcbiAgICAgICAgICBEZWZsYXRlTG9vcCgpO1xuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgICAgICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgICAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgICAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBuYW1lQnVmLmpvaW4oJycpO1xuICAgICAgICAgIGZpbGVzKys7XG4gICAgICAgICAgLy9yZXR1cm4gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgICB9XG4gICAgICAgIHNraXBkaXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gc2tpcGRpcigpIHtcbiAgICB2YXIgY3JjLFxuICAgICAgdG1wID0gW10sXG4gICAgICBjb21wU2l6ZSwgc2l6ZSwgb3MsIGksIGM7XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiA4KSkge1xuICAgICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFsxXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzNdID0gcmVhZEJ5dGUoKTtcblxuICAgICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjUwXCIsIDE2KSAmJlxuICAgICAgICB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLCAxNikgJiZcbiAgICAgICAgdG1wWzJdID09IHBhcnNlSW50KFwiMDdcIiwgMTYpICYmXG4gICAgICAgIHRtcFszXSA9PSBwYXJzZUludChcIjA4XCIsIDE2KSkge1xuICAgICAgICBjcmMgPSByZWFkQnl0ZSgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcmMgPSB0bXBbMF0gfCAodG1wWzFdIDw8IDgpIHwgKHRtcFsyXSA8PCAxNikgfCAodG1wWzNdIDw8IDI0KTtcbiAgICAgIH1cblxuICAgICAgY29tcFNpemUgPSByZWFkQnl0ZSgpO1xuICAgICAgY29tcFNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgIHNpemUgPSByZWFkQnl0ZSgpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJDUkM6XCIpO1xuICAgIH1cblxuICAgIGlmIChtb2RlWklQKVxuICAgICAgbmV4dEZpbGUoKTtcblxuICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgaWYgKHRtcFswXSAhPSA4KSB7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiVW5rbm93biBjb21wcmVzc2lvbiBtZXRob2QhXCIpO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgZ3BmbGFncyA9IHJlYWRCeXRlKCk7XG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBpZiAoKGdwZmxhZ3MgJiB+KHBhcnNlSW50KFwiMWZcIiwgMTYpKSkpXG4gICAgICAgIGFsZXJ0KFwiVW5rbm93biBmbGFncyBzZXQhXCIpO1xuICAgIH1cblxuICAgIHJlYWRCeXRlKCk7XG4gICAgcmVhZEJ5dGUoKTtcbiAgICByZWFkQnl0ZSgpO1xuICAgIHJlYWRCeXRlKCk7XG5cbiAgICByZWFkQnl0ZSgpO1xuICAgIG9zID0gcmVhZEJ5dGUoKTtcblxuICAgIGlmICgoZ3BmbGFncyAmIDQpKSB7XG4gICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzJdID0gcmVhZEJ5dGUoKTtcbiAgICAgIGxlbiA9IHRtcFswXSArIDI1NiAqIHRtcFsxXTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJFeHRyYSBmaWVsZCBzaXplOiBcIiArIGxlbik7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIHJlYWRCeXRlKCk7XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgOCkpIHtcbiAgICAgIGkgPSAwO1xuICAgICAgbmFtZUJ1ZiA9IFtdO1xuICAgICAgd2hpbGUgKGMgPSByZWFkQnl0ZSgpKSB7XG4gICAgICAgIGlmIChjID09IFwiN1wiIHx8IGMgPT0gXCI6XCIpXG4gICAgICAgICAgaSA9IDA7XG4gICAgICAgIGlmIChpIDwgTkFNRU1BWCAtIDEpXG4gICAgICAgICAgbmFtZUJ1ZltpKytdID0gYztcbiAgICAgIH1cbiAgICAgIC8vbmFtZUJ1ZltpXSA9IFwiXFwwXCI7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwib3JpZ2luYWwgZmlsZSBuYW1lOiBcIiArIG5hbWVCdWYpO1xuICAgIH1cblxuICAgIGlmICgoZ3BmbGFncyAmIDE2KSkge1xuICAgICAgd2hpbGUgKGMgPSByZWFkQnl0ZSgpKSB7XG4gICAgICAgIC8vRklMRSBDT01NRU5UXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgMikpIHtcbiAgICAgIHJlYWRCeXRlKCk7XG4gICAgICByZWFkQnl0ZSgpO1xuICAgIH1cblxuICAgIERlZmxhdGVMb29wKCk7XG5cbiAgICBjcmMgPSByZWFkQnl0ZSgpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICBzaXplID0gcmVhZEJ5dGUoKTtcbiAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgaWYgKG1vZGVaSVApXG4gICAgICBuZXh0RmlsZSgpO1xuXG4gIH07XG5cbn07XG5cbi8qKlxuICogIEJhc2U2NCBlbmNvZGluZyAvIGRlY29kaW5nXG4gKiAge0BsaW5rIGh0dHA6Ly93d3cud2VidG9vbGtpdC5pbmZvL31cbiAqL1xuSlhHLlV0aWwuQmFzZTY0ID0ge1xuXG4gIC8vIHByaXZhdGUgcHJvcGVydHlcbiAgX2tleVN0cjogXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiLFxuXG4gIC8vIHB1YmxpYyBtZXRob2QgZm9yIGVuY29kaW5nXG4gIGVuY29kZTogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBjaHIxLCBjaHIyLCBjaHIzLCBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0LFxuICAgICAgaSA9IDA7XG5cbiAgICBpbnB1dCA9IEpYRy5VdGlsLkJhc2U2NC5fdXRmOF9lbmNvZGUoaW5wdXQpO1xuXG4gICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGNocjIgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICBjaHIzID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICBlbmMxID0gY2hyMSA+PiAyO1xuICAgICAgZW5jMiA9ICgoY2hyMSAmIDMpIDw8IDQpIHwgKGNocjIgPj4gNCk7XG4gICAgICBlbmMzID0gKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNik7XG4gICAgICBlbmM0ID0gY2hyMyAmIDYzO1xuXG4gICAgICBpZiAoaXNOYU4oY2hyMikpIHtcbiAgICAgICAgZW5jMyA9IGVuYzQgPSA2NDtcbiAgICAgIH0gZWxzZSBpZiAoaXNOYU4oY2hyMykpIHtcbiAgICAgICAgZW5jNCA9IDY0O1xuICAgICAgfVxuXG4gICAgICBvdXRwdXQucHVzaChbdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMxKSxcbiAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzIpLFxuICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMyksXG4gICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmM0KVxuICAgICAgXS5qb2luKCcnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dC5qb2luKCcnKTtcbiAgfSxcblxuICAvLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZ1xuICBkZWNvZGU6IGZ1bmN0aW9uKGlucHV0LCB1dGY4KSB7XG4gICAgdmFyIG91dHB1dCA9IFtdLFxuICAgICAgY2hyMSwgY2hyMiwgY2hyMyxcbiAgICAgIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsXG4gICAgICBpID0gMDtcblxuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTlcXCtcXC9cXD1dL2csIFwiXCIpO1xuXG4gICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgZW5jMSA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzIgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmMzID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jNCA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblxuICAgICAgY2hyMSA9IChlbmMxIDw8IDIpIHwgKGVuYzIgPj4gNCk7XG4gICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICBjaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0O1xuXG4gICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjEpKTtcblxuICAgICAgaWYgKGVuYzMgIT0gNjQpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjaHIyKSk7XG4gICAgICB9XG4gICAgICBpZiAoZW5jNCAhPSA2NCkge1xuICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjMpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvdXRwdXQgPSBvdXRwdXQuam9pbignJyk7XG5cbiAgICBpZiAodXRmOCkge1xuICAgICAgb3V0cHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2RlY29kZShvdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuXG4gIH0sXG5cbiAgLy8gcHJpdmF0ZSBtZXRob2QgZm9yIFVURi04IGVuY29kaW5nXG4gIF91dGY4X2VuY29kZTogZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoL1xcclxcbi9nLCBcIlxcblwiKTtcbiAgICB2YXIgdXRmdGV4dCA9IFwiXCI7XG5cbiAgICBmb3IgKHZhciBuID0gMDsgbiA8IHN0cmluZy5sZW5ndGg7IG4rKykge1xuXG4gICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KG4pO1xuXG4gICAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICB9IGVsc2UgaWYgKChjID4gMTI3KSAmJiAoYyA8IDIwNDgpKSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiA2KSB8IDE5Mik7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyAmIDYzKSB8IDEyOCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gMTIpIHwgMjI0KTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyA+PiA2KSAmIDYzKSB8IDEyOCk7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyAmIDYzKSB8IDEyOCk7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICByZXR1cm4gdXRmdGV4dDtcbiAgfSxcblxuICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZGVjb2RpbmdcbiAgX3V0ZjhfZGVjb2RlOiBmdW5jdGlvbih1dGZ0ZXh0KSB7XG4gICAgdmFyIHN0cmluZyA9IFtdLFxuICAgICAgaSA9IDAsXG4gICAgICBjID0gMCxcbiAgICAgIGMyID0gMCxcbiAgICAgIGMzID0gMDtcblxuICAgIHdoaWxlIChpIDwgdXRmdGV4dC5sZW5ndGgpIHtcbiAgICAgIGMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgICAgaSsrO1xuICAgICAgfSBlbHNlIGlmICgoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7XG4gICAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAzMSkgPDwgNikgfCAoYzIgJiA2MykpKTtcbiAgICAgICAgaSArPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgICAgaSArPSAzO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3RyaW5nLmpvaW4oJycpO1xuICB9LFxuXG4gIF9kZXN0cmlwOiBmdW5jdGlvbihzdHJpcHBlZCwgd3JhcCkge1xuICAgIHZhciBsaW5lcyA9IFtdLFxuICAgICAgbGluZW5vLCBpLFxuICAgICAgZGVzdHJpcHBlZCA9IFtdO1xuXG4gICAgaWYgKHdyYXAgPT0gbnVsbClcbiAgICAgIHdyYXAgPSA3NjtcblxuICAgIHN0cmlwcGVkLnJlcGxhY2UoLyAvZywgXCJcIik7XG4gICAgbGluZW5vID0gc3RyaXBwZWQubGVuZ3RoIC8gd3JhcDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGluZW5vOyBpKyspXG4gICAgICBsaW5lc1tpXSA9IHN0cmlwcGVkLnN1YnN0cihpICogd3JhcCwgd3JhcCk7XG4gICAgaWYgKGxpbmVubyAhPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwKVxuICAgICAgbGluZXNbbGluZXMubGVuZ3RoXSA9IHN0cmlwcGVkLnN1YnN0cihsaW5lbm8gKiB3cmFwLCBzdHJpcHBlZC5sZW5ndGggLSAobGluZW5vICogd3JhcCkpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKVxuICAgICAgZGVzdHJpcHBlZC5wdXNoKGxpbmVzW2ldKTtcbiAgICByZXR1cm4gZGVzdHJpcHBlZC5qb2luKCdcXG4nKTtcbiAgfSxcblxuICBkZWNvZGVBc0FycmF5OiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBkZWMgPSB0aGlzLmRlY29kZShpbnB1dCksXG4gICAgICBhciA9IFtdLFxuICAgICAgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZGVjLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcltpXSA9IGRlYy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgICByZXR1cm4gYXI7XG4gIH0sXG5cbiAgZGVjb2RlR0VPTkV4VDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICByZXR1cm4gZGVjb2RlQXNBcnJheShkZXN0cmlwKGlucHV0KSwgZmFsc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbkpYRy5VdGlsLmFzY2lpQ2hhckNvZGVBdCA9IGZ1bmN0aW9uKHN0ciwgaSkge1xuICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICBpZiAoYyA+IDI1NSkge1xuICAgIHN3aXRjaCAoYykge1xuICAgICAgY2FzZSA4MzY0OlxuICAgICAgICBjID0gMTI4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxODpcbiAgICAgICAgYyA9IDEzMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQwMjpcbiAgICAgICAgYyA9IDEzMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjI6XG4gICAgICAgIGMgPSAxMzI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjMwOlxuICAgICAgICBjID0gMTMzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyNDpcbiAgICAgICAgYyA9IDEzNDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjU6XG4gICAgICAgIGMgPSAxMzU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3MTA6XG4gICAgICAgIGMgPSAxMzY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjQwOlxuICAgICAgICBjID0gMTM3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzUyOlxuICAgICAgICBjID0gMTM4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODI0OTpcbiAgICAgICAgYyA9IDEzOTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMzODpcbiAgICAgICAgYyA9IDE0MDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM4MTpcbiAgICAgICAgYyA9IDE0MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTY6XG4gICAgICAgIGMgPSAxNDU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjE3OlxuICAgICAgICBjID0gMTQ2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMDpcbiAgICAgICAgYyA9IDE0NztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjE6XG4gICAgICAgIGMgPSAxNDg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjI2OlxuICAgICAgICBjID0gMTQ5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxMTpcbiAgICAgICAgYyA9IDE1MDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTI6XG4gICAgICAgIGMgPSAxNTE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3MzI6XG4gICAgICAgIGMgPSAxNTI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4NDgyOlxuICAgICAgICBjID0gMTUzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzUzOlxuICAgICAgICBjID0gMTU0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODI1MDpcbiAgICAgICAgYyA9IDE1NTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMzOTpcbiAgICAgICAgYyA9IDE1NjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM4MjpcbiAgICAgICAgYyA9IDE1ODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM3NjpcbiAgICAgICAgYyA9IDE1OTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGM7XG59O1xuXG4vKipcbiAqIERlY29kaW5nIHN0cmluZyBpbnRvIHV0Zi04XG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybiB7U3RyaW5nfSB1dGY4IGRlY29kZWQgc3RyaW5nXG4gKi9cbkpYRy5VdGlsLnV0ZjhEZWNvZGUgPSBmdW5jdGlvbih1dGZ0ZXh0KSB7XG4gIHZhciBzdHJpbmcgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIgYyA9IDAsXG4gICAgYzEgPSAwLFxuICAgIGMyID0gMCxcbiAgICBjMztcbiAgaWYgKCFKWEcuZXhpc3RzKHV0ZnRleHQpKSByZXR1cm4gJyc7XG5cbiAgd2hpbGUgKGkgPCB1dGZ0ZXh0Lmxlbmd0aCkge1xuICAgIGMgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSk7XG5cbiAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjKSk7XG4gICAgICBpKys7XG4gICAgfSBlbHNlIGlmICgoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7XG4gICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpO1xuICAgICAgaSArPSAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDE1KSA8PCAxMikgfCAoKGMyICYgNjMpIDw8IDYpIHwgKGMzICYgNjMpKSk7XG4gICAgICBpICs9IDM7XG4gICAgfVxuICB9O1xuICByZXR1cm4gc3RyaW5nLmpvaW4oJycpO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHJhbmRvbSB1dWlkLlxuICogaHR0cDovL3d3dy5icm9vZmEuY29tXG4gKiBtYWlsdG86cm9iZXJ0QGJyb29mYS5jb21cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAgUm9iZXJ0IEtpZWZmZXJcbiAqIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBhbmQgR1BMIGxpY2Vuc2VzLlxuICpcbiAqIEVYQU1QTEVTOlxuICogICA+Pj4gTWF0aC51dWlkKClcbiAqICAgXCI5MjMyOUQzOS02RjVDLTQ1MjAtQUJGQy1BQUI2NDU0NEUxNzJcIlxuICovXG5KWEcuVXRpbC5nZW5VVUlEID0gZnVuY3Rpb24oKSB7XG4gIC8vIFByaXZhdGUgYXJyYXkgb2YgY2hhcnMgdG8gdXNlXG4gIHZhciBjaGFycyA9ICcwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eicuc3BsaXQoJycpLFxuICAgIHV1aWQgPSBuZXcgQXJyYXkoMzYpLFxuICAgIHJuZCA9IDAsXG4gICAgcjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDM2OyBpKyspIHtcbiAgICBpZiAoaSA9PSA4IHx8IGkgPT0gMTMgfHwgaSA9PSAxOCB8fCBpID09IDIzKSB7XG4gICAgICB1dWlkW2ldID0gJy0nO1xuICAgIH0gZWxzZSBpZiAoaSA9PSAxNCkge1xuICAgICAgdXVpZFtpXSA9ICc0JztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJuZCA8PSAweDAyKSBybmQgPSAweDIwMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMCkgfCAwO1xuICAgICAgciA9IHJuZCAmIDB4ZjtcbiAgICAgIHJuZCA9IHJuZCA+PiA0O1xuICAgICAgdXVpZFtpXSA9IGNoYXJzWyhpID09IDE5KSA/IChyICYgMHgzKSB8IDB4OCA6IHJdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1dWlkLmpvaW4oJycpO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpYRztcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy9cbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vL1xuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogVGhpcyBvYmplY3QgY29udGFpbnMgY29uZmlndXJhdGlvbiB2YWx1ZXMuXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gcHJlZmVyX2hhc2hfYWxnb3JpdGhtXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGVuY3J5cHRpb25fY2lwaGVyXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGNvbXByZXNzaW9uXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNob3dfdmVyc2lvblxuICogQHByb3BlcnR5IHtCb29sZWFufSBzaG93X2NvbW1lbnRcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gaW50ZWdyaXR5X3Byb3RlY3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBrZXlzZXJ2ZXJcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZGVidWcgSWYgZW5hYmxlZCwgZGVidWcgbWVzc2FnZXMgd2lsbCBiZSBwcmludGVkXG4gKiBAbW9kdWxlIGNvbmZpZy9jb25maWdcbiAqL1xuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcHJlZmVyX2hhc2hfYWxnb3JpdGhtOiBlbnVtcy5oYXNoLnNoYTI1NixcbiAgZW5jcnlwdGlvbl9jaXBoZXI6IGVudW1zLnN5bW1ldHJpYy5hZXMyNTYsXG4gIGNvbXByZXNzaW9uOiBlbnVtcy5jb21wcmVzc2lvbi56aXAsXG4gIHNob3dfdmVyc2lvbjogdHJ1ZSxcbiAgc2hvd19jb21tZW50OiB0cnVlLFxuICBpbnRlZ3JpdHlfcHJvdGVjdDogdHJ1ZSxcbiAga2V5c2VydmVyOiBcImtleXNlcnZlci5saW51eC5pdFwiLCAvLyBcInBncC5taXQuZWR1OjExMzcxXCJcblxuICB2ZXJzaW9uc3RyaW5nOiBcIk9wZW5QR1AuanMgVkVSU0lPTlwiLFxuICBjb21tZW50c3RyaW5nOiBcImh0dHA6Ly9vcGVucGdwanMub3JnXCIsXG5cbiAgZGVidWc6IGZhbHNlXG59O1xuIiwiLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuXG4vLyBtb2RpZmllZCB2ZXJzaW9uIG9mIGh0dHA6Ly93d3cuaGFuZXdpbi5uZXQvZW5jcnlwdC9QR2RlY29kZS5qczpcblxuLyogT3BlblBHUCBlbmNyeXB0aW9uIHVzaW5nIFJTQS9BRVNcbiAqIENvcHlyaWdodCAyMDA1LTIwMDYgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAyLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXJcbiAqIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxuLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2NpcGhlclxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgY3J5cHRvL2NmYlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjaXBoZXIgPSByZXF1aXJlKCcuL2NpcGhlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBlbmNyeXB0cyBhIGdpdmVuIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXhyYW5kb20gXG4gICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgYmxvY2tjaXBoZXIgdG8gZW5jcnlwdCBhIG1lc3NhZ2VcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeHJhbmRvbSByYW5kb20gYnl0ZXMgb2YgYmxvY2tfc2l6ZSBsZW5ndGggcHJvdmlkZWQgXG4gICAqICBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGluIHByZWZpeGluZyB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2lwaGVyZm4gdGhlIGFsZ29yaXRobSBjaXBoZXIgY2xhc3MgdG8gZW5jcnlwdFxuICAgKiAgZGF0YSBpbiBvbmUgYmxvY2tfc2l6ZSBlbmNyeXB0aW9uLCBAc2VlIG1vZHVsZTpjcnlwdG8vY2lwaGVyLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGxhaW50ZXh0IGRhdGEgdG8gYmUgZW5jcnlwdGVkIHByb3ZpZGVkIGFzIGEgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBwbGFpbnRleHQuXG4gICAqIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGNpcGhlcmZuXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVzeW5jIGEgYm9vbGVhbiB2YWx1ZSBzcGVjaWZ5aW5nIGlmIGEgcmVzeW5jIG9mIHRoZVxuICAgKiAgSVYgc2hvdWxkIGJlIHVzZWQgb3Igbm90LiBUaGUgZW5jcnlwdGVkZGF0YXBhY2tldCB1c2VzIHRoZSBcbiAgICogIFwib2xkXCIgc3R5bGUgd2l0aCBhIHJlc3luYy4gRW5jcnlwdGlvbiB3aXRoaW4gYW4gXG4gICAqICBlbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhIHBhY2tldCBpcyBub3QgcmVzeW5jaW5nIHRoZSBJVi5cbiAgICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyB3aXRoIHRoZSBlbmNyeXB0ZWQgZGF0YVxuICAgKi9cbiAgZW5jcnlwdDogZnVuY3Rpb24ocHJlZml4cmFuZG9tLCBjaXBoZXJmbiwgcGxhaW50ZXh0LCBrZXksIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBGUiA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgRlJFID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuXG4gICAgcHJlZml4cmFuZG9tID0gcHJlZml4cmFuZG9tICsgcHJlZml4cmFuZG9tLmNoYXJBdChibG9ja19zaXplIC0gMikgKyBwcmVmaXhyYW5kb20uY2hhckF0KGJsb2NrX3NpemUgLSAxKTtcbiAgICB1dGlsLnByaW50X2RlYnVnKFwicHJlZml4cmFuZG9tOlwiICsgdXRpbC5oZXhzdHJkdW1wKHByZWZpeHJhbmRvbSkpO1xuICAgIHZhciBjaXBoZXJ0ZXh0ID0gXCJcIjtcbiAgICAvLyAxLiAgVGhlIGZlZWRiYWNrIHJlZ2lzdGVyIChGUikgaXMgc2V0IHRvIHRoZSBJViwgd2hpY2ggaXMgYWxsIHplcm9zLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IDA7XG5cbiAgICAvLyAyLiAgRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFIChGUiBFbmNyeXB0ZWQpLiAgVGhpcyBpcyB0aGVcbiAgICAvLyAgICAgZW5jcnlwdGlvbiBvZiBhbiBhbGwtemVybyB2YWx1ZS5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcbiAgICAvLyAzLiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IEJTIG9jdGV0cyBvZiByYW5kb20gZGF0YSBwcmVmaXhlZCB0b1xuICAgIC8vICAgICB0aGUgcGxhaW50ZXh0IHRvIHByb2R1Y2UgQ1sxXSB0aHJvdWdoIENbQlNdLCB0aGUgZmlyc3QgQlMgb2N0ZXRzXG4gICAgLy8gICAgIG9mIGNpcGhlcnRleHQuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChpKSk7XG5cbiAgICAvLyA0LiAgRlIgaXMgbG9hZGVkIHdpdGggQ1sxXSB0aHJvdWdoIENbQlNdLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIC8vIDUuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUsIHRoZSBlbmNyeXB0aW9uIG9mIHRoZSBmaXJzdCBCU1xuICAgIC8vIFx0ICAgb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAvLyA2LiAgVGhlIGxlZnQgdHdvIG9jdGV0cyBvZiBGUkUgZ2V0IHhvcmVkIHdpdGggdGhlIG5leHQgdHdvIG9jdGV0cyBvZlxuICAgIC8vICAgICBkYXRhIHRoYXQgd2VyZSBwcmVmaXhlZCB0byB0aGUgcGxhaW50ZXh0LiAgVGhpcyBwcm9kdWNlcyBDW0JTKzFdXG4gICAgLy8gICAgIGFuZCBDW0JTKzJdLCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVswXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKTtcbiAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzFdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDcuICAoVGhlIHJlc3luYyBzdGVwKSBGUiBpcyBsb2FkZWQgd2l0aCBDMy1DMTAuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIC8vIDguICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuXG4gICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUiwga2V5KTtcblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKylcbiAgICAgICAgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemUgKyAyOyBuIDwgcGxhaW50ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIC8vIDEwLiBGUiBpcyBsb2FkZWQgd2l0aCBDMTEtQzE4XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuICsgaSk7XG5cbiAgICAgICAgLy8gMTEuIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cbiAgICAgICAgRlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cbiAgICAgICAgLy8gMTIuIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBuZXh0IDggb2N0ZXRzIG9mIHBsYWludGV4dCwgdG8gcHJvZHVjZSB0aGVcbiAgICAgICAgLy8gbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoKG4gLSAyKSArXG4gICAgICAgICAgICBpKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBsYWludGV4dCA9IFwiICBcIiArIHBsYWludGV4dDtcbiAgICAgIC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG4gICAgICAvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuICAgICAgLy8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG4gICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGJsb2NrX3NpemU7IGkrKykgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIHZhciB0ZW1wQ2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIDIgKiBibG9ja19zaXplKS5zcGxpdCgnJyk7XG4gICAgICB2YXIgdGVtcENpcGhlcnRleHRTdHJpbmcgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZyhibG9ja19zaXplKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBwbGFpbnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gdGVtcENpcGhlcnRleHRTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgICAgdGVtcENpcGhlcnRleHRTdHJpbmcgPSAnJztcblxuICAgICAgICAvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuICAgICAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgICAgICAvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZVxuICAgICAgICAvLyAgICAgbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcbiAgICAgICAgLy8gICAgIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgdGhlIHBsYWludGV4dCBpcyB1c2VkIHVwLlxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgICAgIHRlbXBDaXBoZXJ0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdChuICsgaSkpKTtcbiAgICAgICAgICB0ZW1wQ2lwaGVydGV4dFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4gKyBpKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNpcGhlcnRleHQgPSB0ZW1wQ2lwaGVydGV4dC5qb2luKCcnKTtcblxuICAgIH1cblxuICAgIGNpcGhlcnRleHQgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZygwLCBwbGFpbnRleHQubGVuZ3RoICsgMiArIGJsb2NrX3NpemUpO1xuXG4gICAgcmV0dXJuIGNpcGhlcnRleHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcmVmaXhlZCBkYXRhIGZvciB0aGUgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlIChNREMpIGNvbXB1dGF0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaXBoZXJmbi5lbmNyeXB0IENpcGhlciBmdW5jdGlvbiB0byB1c2UsXG4gICAqICBAc2VlIG1vZHVsZTpjcnlwdG8vY2lwaGVyLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2Yga2V5IHRvIGJlIHVzZWQgdG8gY2hlY2sgdGhlIG1kY1xuICAgKiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjaXBoZXJmblxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2lwaGVydGV4dCBUaGUgZW5jcnlwdGVkIGRhdGFcbiAgICogQHJldHVybiB7U3RyaW5nfSBwbGFpbnRleHQgRGF0YSBvZiBEKGNpcGhlcnRleHQpIHdpdGggYmxvY2tzaXplIGxlbmd0aCArMlxuICAgKi9cbiAgbWRjOiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBjaXBoZXJ0ZXh0KSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGlibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgYWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBpO1xuXG5cbiAgICAvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3JcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwO1xuXG4gICAgaWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIHtcbiAgICAgIGFibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGlibG9ja1tpXSBePSBhYmxvY2tbaV07XG4gICAgfVxuXG4gICAgYWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChhYmxvY2spO1xuXG4gICAgcmV0dXJuIHV0aWwuYmluMnN0cihpYmxvY2spICtcbiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzBdIF4gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKSArXG4gICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1sxXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplICsgMSkpO1xuICB9LFxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBkZWNyeXB0cyBhIGdpdmVuIHBsYWludGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkXG4gICAqIGJsb2NrY2lwaGVyIHRvIGRlY3J5cHQgYSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaXBoZXJmbiB0aGUgYWxnb3JpdGhtIGNpcGhlciBjbGFzcyB0byBkZWNyeXB0XG4gICAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24sIEBzZWUgbW9kdWxlOmNyeXB0by9jaXBoZXIuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBrZXkgdG8gYmUgdXNlZCB0byBkZWNyeXB0IHRoZSBjaXBoZXJ0ZXh0LlxuICAgKiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjaXBoZXJmblxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2lwaGVydGV4dCB0byBiZSBkZWNyeXB0ZWQgcHJvdmlkZWQgYXMgYSBzdHJpbmdcbiAgICogQHBhcmFtIHtCb29sZWFufSByZXN5bmMgYSBib29sZWFuIHZhbHVlIHNwZWNpZnlpbmcgaWYgYSByZXN5bmMgb2YgdGhlXG4gICAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIFxuICAgKiAgXCJvbGRcIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBEZWNyeXB0aW9uIHdpdGhpbiBhbiBcbiAgICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHdpdGggdGhlIHBsYWludGV4dCBkYXRhXG4gICAqL1xuXG4gIGRlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIHJlc3luYykge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgaSwgbiA9ICcnO1xuICAgIHZhciB0ZXh0ID0gW107XG5cbiAgICAvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3JcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwO1xuXG4gICAgaWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2ssIGtleSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykge1xuICAgICAgYWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWJsb2NrW2ldIF49IGFibG9ja1tpXTtcbiAgICB9XG5cbiAgICBhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGFibG9jaywga2V5KTtcblxuICAgIC8vIHRlc3QgY2hlY2sgb2N0ZXRzXG4gICAgaWYgKGlibG9ja1tibG9ja19zaXplIC0gMl0gIT0gKGFibG9ja1swXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkgfHwgaWJsb2NrW2Jsb2NrX3NpemUgLSAxXSAhPSAoYWJsb2NrW1xuICAgICAgMV0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEuJyk7XG4gICAgfVxuXG4gICAgLyogIFJGQzQ4ODA6IFRhZyAxOCBhbmQgUmVzeW5jOlxuXHRcdCAqICBbLi4uXSBVbmxpa2UgdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCBub1xuXHRcdCAqICBzcGVjaWFsIENGQiByZXN5bmNocm9uaXphdGlvbiBpcyBkb25lIGFmdGVyIGVuY3J5cHRpbmcgdGhpcyBwcmVmaXhcblx0XHQgKiAgZGF0YS4gIFNlZSBcIk9wZW5QR1AgQ0ZCIE1vZGVcIiBiZWxvdyBmb3IgbW9yZSBkZXRhaWxzLlxuXG5cdFx0ICovXG5cbiAgICBpZiAocmVzeW5jKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSArIDIpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZSArIDI7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZSAmJiBpICsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobiArIGkpO1xuICAgICAgICAgIHRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1tpXSBeIGlibG9ja1tpXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGZvciAobiA9IGJsb2NrX3NpemU7IG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgbiArPSBibG9ja19zaXplKSB7XG4gICAgICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemUgJiYgaSArIG4gPCBjaXBoZXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4gKyBpKTtcbiAgICAgICAgICB0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbaV0gXiBpYmxvY2tbaV0pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuID0gcmVzeW5jID8gMCA6IDI7XG5cbiAgICB0ZXh0ID0gdGV4dC5qb2luKCcnKTtcblxuICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZyhuLCBjaXBoZXJ0ZXh0Lmxlbmd0aCAtIGJsb2NrX3NpemUgLSAyICsgbik7XG5cblxuICAgIHJldHVybiB0ZXh0O1xuICB9LFxuXG5cbiAgbm9ybWFsRW5jcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgcGxhaW50ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja2kgPSBcIlwiO1xuICAgIHZhciBibG9ja2MgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBjeXBoZXJ0ZXh0ID0gW107XG4gICAgdmFyIHRlbXBCbG9jayA9IFtdO1xuICAgIGJsb2NrYyA9IGl2LnN1YnN0cmluZygwLCBibG9ja19zaXplKTtcbiAgICB3aGlsZSAocGxhaW50ZXh0Lmxlbmd0aCA+IGJsb2NrX3NpemUgKiBwb3MpIHtcbiAgICAgIHZhciBlbmNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrYykpO1xuICAgICAgYmxvY2tpID0gcGxhaW50ZXh0LnN1YnN0cmluZygocG9zICogYmxvY2tfc2l6ZSksIChwb3MgKiBibG9ja19zaXplKSArIGJsb2NrX3NpemUpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja2kubGVuZ3RoOyBpKyspXG4gICAgICAgIHRlbXBCbG9jay5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2tpLmNoYXJDb2RlQXQoaSkgXiBlbmNibG9ja1tpXSkpO1xuICAgICAgYmxvY2tjID0gdGVtcEJsb2NrLmpvaW4oJycpO1xuICAgICAgdGVtcEJsb2NrID0gW107XG4gICAgICBjeXBoZXJ0ZXh0LnB1c2goYmxvY2tjKTtcbiAgICAgIHBvcysrO1xuICAgIH1cbiAgICByZXR1cm4gY3lwaGVydGV4dC5qb2luKCcnKTtcbiAgfSxcblxuICBub3JtYWxEZWNyeXB0OiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBjaXBoZXJ0ZXh0LCBpdikge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBibG9ja3AgPSBcIlwiO1xuICAgIHZhciBwb3MgPSAwO1xuICAgIHZhciBwbGFpbnRleHQgPSBbXTtcbiAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICBpZiAoaXYgPT0gbnVsbClcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBibG9ja3AgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICBlbHNlXG4gICAgICBibG9ja3AgPSBpdi5zdWJzdHJpbmcoMCwgYmxvY2tfc2l6ZSk7XG4gICAgd2hpbGUgKGNpcGhlcnRleHQubGVuZ3RoID4gKGJsb2NrX3NpemUgKiBwb3MpKSB7XG4gICAgICB2YXIgZGVjYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KHV0aWwuc3RyMmJpbihibG9ja3ApKTtcbiAgICAgIGJsb2NrcCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKChwb3MgKiAoYmxvY2tfc2l6ZSkpICsgb2Zmc2V0LCAocG9zICogKGJsb2NrX3NpemUpKSArIChibG9ja19zaXplKSArIG9mZnNldCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrcC5sZW5ndGg7IGkrKykge1xuICAgICAgICBwbGFpbnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJsb2NrcC5jaGFyQ29kZUF0KGkpIF4gZGVjYmxvY2tbaV0pKTtcbiAgICAgIH1cbiAgICAgIHBvcysrO1xuICAgIH1cblxuICAgIHJldHVybiBwbGFpbnRleHQuam9pbignJyk7XG4gIH1cbn1cbiIsIi8qIFJpam5kYWVsIChBRVMpIEVuY3J5cHRpb25cbiAqIENvcHlyaWdodCAyMDA1IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMS4xLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvclxuICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnlcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcbiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3RcbiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyXG4gKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxuICovXG5cbi8qKlxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgY3J5cHRvL2NpcGhlci9hZXNcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gVGhlIHJvdW5kIGNvbnN0YW50cyB1c2VkIGluIHN1YmtleSBleHBhbnNpb25cbnZhciBSY29uID0gW1xuICAgIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzYsIDB4NmMsIDB4ZDgsXG4gICAgMHhhYiwgMHg0ZCwgMHg5YSwgMHgyZiwgMHg1ZSwgMHhiYywgMHg2MywgMHhjNiwgMHg5NywgMHgzNSwgMHg2YSwgMHhkNCxcbiAgICAweGIzLCAweDdkLCAweGZhLCAweGVmLCAweGM1LCAweDkxXG5dO1xuXG4vLyBQcmVjb21wdXRlZCBsb29rdXAgdGFibGUgZm9yIHRoZSBTQm94XG52YXIgUyA9IFtcbiAgICA5OSwgMTI0LCAxMTksIDEyMywgMjQyLCAxMDcsIDExMSwgMTk3LCA0OCwgMSwgMTAzLCA0MywgMjU0LCAyMTUsIDE3MSxcbiAgICAxMTgsIDIwMiwgMTMwLCAyMDEsIDEyNSwgMjUwLCA4OSwgNzEsIDI0MCwgMTczLCAyMTIsIDE2MiwgMTc1LCAxNTYsIDE2NCxcbiAgICAxMTQsIDE5MiwgMTgzLCAyNTMsIDE0NywgMzgsIDU0LCA2MywgMjQ3LCAyMDQsIDUyLCAxNjUsIDIyOSwgMjQxLCAxMTMsXG4gICAgMjE2LCA0OSwgMjEsIDQsIDE5OSwgMzUsIDE5NSwgMjQsIDE1MCwgNSwgMTU0LCA3LCAxOCwgMTI4LCAyMjYsXG4gICAgMjM1LCAzOSwgMTc4LCAxMTcsIDksIDEzMSwgNDQsIDI2LCAyNywgMTEwLCA5MCwgMTYwLCA4MiwgNTksIDIxNCxcbiAgICAxNzksIDQxLCAyMjcsIDQ3LCAxMzIsIDgzLCAyMDksIDAsIDIzNywgMzIsIDI1MiwgMTc3LCA5MSwgMTA2LCAyMDMsXG4gICAgMTkwLCA1NywgNzQsIDc2LCA4OCwgMjA3LCAyMDgsIDIzOSwgMTcwLCAyNTEsIDY3LCA3NywgNTEsIDEzMywgNjksXG4gICAgMjQ5LCAyLCAxMjcsIDgwLCA2MCwgMTU5LCAxNjgsIDgxLCAxNjMsIDY0LCAxNDMsIDE0NiwgMTU3LCA1NiwgMjQ1LFxuICAgIDE4OCwgMTgyLCAyMTgsIDMzLCAxNiwgMjU1LCAyNDMsIDIxMCwgMjA1LCAxMiwgMTksIDIzNiwgOTUsIDE1MSwgNjgsXG4gICAgMjMsIDE5NiwgMTY3LCAxMjYsIDYxLCAxMDAsIDkzLCAyNSwgMTE1LCA5NiwgMTI5LCA3OSwgMjIwLCAzNCwgNDIsXG4gICAgMTQ0LCAxMzYsIDcwLCAyMzgsIDE4NCwgMjAsIDIyMiwgOTQsIDExLCAyMTksIDIyNCwgNTAsIDU4LCAxMCwgNzMsXG4gICAgNiwgMzYsIDkyLCAxOTQsIDIxMSwgMTcyLCA5OCwgMTQ1LCAxNDksIDIyOCwgMTIxLCAyMzEsIDIwMCwgNTUsIDEwOSxcbiAgICAxNDEsIDIxMywgNzgsIDE2OSwgMTA4LCA4NiwgMjQ0LCAyMzQsIDEwMSwgMTIyLCAxNzQsIDgsIDE4NiwgMTIwLCAzNyxcbiAgICA0NiwgMjgsIDE2NiwgMTgwLCAxOTgsIDIzMiwgMjIxLCAxMTYsIDMxLCA3NSwgMTg5LCAxMzksIDEzOCwgMTEyLCA2MixcbiAgICAxODEsIDEwMiwgNzIsIDMsIDI0NiwgMTQsIDk3LCA1MywgODcsIDE4NSwgMTM0LCAxOTMsIDI5LCAxNTgsIDIyNSxcbiAgICAyNDgsIDE1MiwgMTcsIDEwNSwgMjE3LCAxNDIsIDE0OCwgMTU1LCAzMCwgMTM1LCAyMzMsIDIwNiwgODUsIDQwLCAyMjMsXG4gICAgMTQwLCAxNjEsIDEzNywgMTMsIDE5MSwgMjMwLCA2NiwgMTA0LCA2NSwgMTUzLCA0NSwgMTUsIDE3NiwgODQsIDE4NyxcbiAgICAyMlxuXTtcblxudmFyIFQxID0gW1xuICAgIDB4YTU2MzYzYzYsIDB4ODQ3YzdjZjgsIDB4OTk3Nzc3ZWUsIDB4OGQ3YjdiZjYsXG4gICAgMHgwZGYyZjJmZiwgMHhiZDZiNmJkNiwgMHhiMTZmNmZkZSwgMHg1NGM1YzU5MSxcbiAgICAweDUwMzAzMDYwLCAweDAzMDEwMTAyLCAweGE5Njc2N2NlLCAweDdkMmIyYjU2LFxuICAgIDB4MTlmZWZlZTcsIDB4NjJkN2Q3YjUsIDB4ZTZhYmFiNGQsIDB4OWE3Njc2ZWMsXG4gICAgMHg0NWNhY2E4ZiwgMHg5ZDgyODIxZiwgMHg0MGM5Yzk4OSwgMHg4NzdkN2RmYSxcbiAgICAweDE1ZmFmYWVmLCAweGViNTk1OWIyLCAweGM5NDc0NzhlLCAweDBiZjBmMGZiLFxuICAgIDB4ZWNhZGFkNDEsIDB4NjdkNGQ0YjMsIDB4ZmRhMmEyNWYsIDB4ZWFhZmFmNDUsXG4gICAgMHhiZjljOWMyMywgMHhmN2E0YTQ1MywgMHg5NjcyNzJlNCwgMHg1YmMwYzA5YixcbiAgICAweGMyYjdiNzc1LCAweDFjZmRmZGUxLCAweGFlOTM5MzNkLCAweDZhMjYyNjRjLFxuICAgIDB4NWEzNjM2NmMsIDB4NDEzZjNmN2UsIDB4MDJmN2Y3ZjUsIDB4NGZjY2NjODMsXG4gICAgMHg1YzM0MzQ2OCwgMHhmNGE1YTU1MSwgMHgzNGU1ZTVkMSwgMHgwOGYxZjFmOSxcbiAgICAweDkzNzE3MWUyLCAweDczZDhkOGFiLCAweDUzMzEzMTYyLCAweDNmMTUxNTJhLFxuICAgIDB4MGMwNDA0MDgsIDB4NTJjN2M3OTUsIDB4NjUyMzIzNDYsIDB4NWVjM2MzOWQsXG4gICAgMHgyODE4MTgzMCwgMHhhMTk2OTYzNywgMHgwZjA1MDUwYSwgMHhiNTlhOWEyZixcbiAgICAweDA5MDcwNzBlLCAweDM2MTIxMjI0LCAweDliODA4MDFiLCAweDNkZTJlMmRmLFxuICAgIDB4MjZlYmViY2QsIDB4NjkyNzI3NGUsIDB4Y2RiMmIyN2YsIDB4OWY3NTc1ZWEsXG4gICAgMHgxYjA5MDkxMiwgMHg5ZTgzODMxZCwgMHg3NDJjMmM1OCwgMHgyZTFhMWEzNCxcbiAgICAweDJkMWIxYjM2LCAweGIyNmU2ZWRjLCAweGVlNWE1YWI0LCAweGZiYTBhMDViLFxuICAgIDB4ZjY1MjUyYTQsIDB4NGQzYjNiNzYsIDB4NjFkNmQ2YjcsIDB4Y2ViM2IzN2QsXG4gICAgMHg3YjI5Mjk1MiwgMHgzZWUzZTNkZCwgMHg3MTJmMmY1ZSwgMHg5Nzg0ODQxMyxcbiAgICAweGY1NTM1M2E2LCAweDY4ZDFkMWI5LCAweDAwMDAwMDAwLCAweDJjZWRlZGMxLFxuICAgIDB4NjAyMDIwNDAsIDB4MWZmY2ZjZTMsIDB4YzhiMWIxNzksIDB4ZWQ1YjViYjYsXG4gICAgMHhiZTZhNmFkNCwgMHg0NmNiY2I4ZCwgMHhkOWJlYmU2NywgMHg0YjM5Mzk3MixcbiAgICAweGRlNGE0YTk0LCAweGQ0NGM0Yzk4LCAweGU4NTg1OGIwLCAweDRhY2ZjZjg1LFxuICAgIDB4NmJkMGQwYmIsIDB4MmFlZmVmYzUsIDB4ZTVhYWFhNGYsIDB4MTZmYmZiZWQsXG4gICAgMHhjNTQzNDM4NiwgMHhkNzRkNGQ5YSwgMHg1NTMzMzM2NiwgMHg5NDg1ODUxMSxcbiAgICAweGNmNDU0NThhLCAweDEwZjlmOWU5LCAweDA2MDIwMjA0LCAweDgxN2Y3ZmZlLFxuICAgIDB4ZjA1MDUwYTAsIDB4NDQzYzNjNzgsIDB4YmE5ZjlmMjUsIDB4ZTNhOGE4NGIsXG4gICAgMHhmMzUxNTFhMiwgMHhmZWEzYTM1ZCwgMHhjMDQwNDA4MCwgMHg4YThmOGYwNSxcbiAgICAweGFkOTI5MjNmLCAweGJjOWQ5ZDIxLCAweDQ4MzgzODcwLCAweDA0ZjVmNWYxLFxuICAgIDB4ZGZiY2JjNjMsIDB4YzFiNmI2NzcsIDB4NzVkYWRhYWYsIDB4NjMyMTIxNDIsXG4gICAgMHgzMDEwMTAyMCwgMHgxYWZmZmZlNSwgMHgwZWYzZjNmZCwgMHg2ZGQyZDJiZixcbiAgICAweDRjY2RjZDgxLCAweDE0MGMwYzE4LCAweDM1MTMxMzI2LCAweDJmZWNlY2MzLFxuICAgIDB4ZTE1ZjVmYmUsIDB4YTI5Nzk3MzUsIDB4Y2M0NDQ0ODgsIDB4MzkxNzE3MmUsXG4gICAgMHg1N2M0YzQ5MywgMHhmMmE3YTc1NSwgMHg4MjdlN2VmYywgMHg0NzNkM2Q3YSxcbiAgICAweGFjNjQ2NGM4LCAweGU3NWQ1ZGJhLCAweDJiMTkxOTMyLCAweDk1NzM3M2U2LFxuICAgIDB4YTA2MDYwYzAsIDB4OTg4MTgxMTksIDB4ZDE0ZjRmOWUsIDB4N2ZkY2RjYTMsXG4gICAgMHg2NjIyMjI0NCwgMHg3ZTJhMmE1NCwgMHhhYjkwOTAzYiwgMHg4Mzg4ODgwYixcbiAgICAweGNhNDY0NjhjLCAweDI5ZWVlZWM3LCAweGQzYjhiODZiLCAweDNjMTQxNDI4LFxuICAgIDB4NzlkZWRlYTcsIDB4ZTI1ZTVlYmMsIDB4MWQwYjBiMTYsIDB4NzZkYmRiYWQsXG4gICAgMHgzYmUwZTBkYiwgMHg1NjMyMzI2NCwgMHg0ZTNhM2E3NCwgMHgxZTBhMGExNCxcbiAgICAweGRiNDk0OTkyLCAweDBhMDYwNjBjLCAweDZjMjQyNDQ4LCAweGU0NWM1Y2I4LFxuICAgIDB4NWRjMmMyOWYsIDB4NmVkM2QzYmQsIDB4ZWZhY2FjNDMsIDB4YTY2MjYyYzQsXG4gICAgMHhhODkxOTEzOSwgMHhhNDk1OTUzMSwgMHgzN2U0ZTRkMywgMHg4Yjc5NzlmMixcbiAgICAweDMyZTdlN2Q1LCAweDQzYzhjODhiLCAweDU5MzczNzZlLCAweGI3NmQ2ZGRhLFxuICAgIDB4OGM4ZDhkMDEsIDB4NjRkNWQ1YjEsIDB4ZDI0ZTRlOWMsIDB4ZTBhOWE5NDksXG4gICAgMHhiNDZjNmNkOCwgMHhmYTU2NTZhYywgMHgwN2Y0ZjRmMywgMHgyNWVhZWFjZixcbiAgICAweGFmNjU2NWNhLCAweDhlN2E3YWY0LCAweGU5YWVhZTQ3LCAweDE4MDgwODEwLFxuICAgIDB4ZDViYWJhNmYsIDB4ODg3ODc4ZjAsIDB4NmYyNTI1NGEsIDB4NzIyZTJlNWMsXG4gICAgMHgyNDFjMWMzOCwgMHhmMWE2YTY1NywgMHhjN2I0YjQ3MywgMHg1MWM2YzY5NyxcbiAgICAweDIzZThlOGNiLCAweDdjZGRkZGExLCAweDljNzQ3NGU4LCAweDIxMWYxZjNlLFxuICAgIDB4ZGQ0YjRiOTYsIDB4ZGNiZGJkNjEsIDB4ODY4YjhiMGQsIDB4ODU4YThhMGYsXG4gICAgMHg5MDcwNzBlMCwgMHg0MjNlM2U3YywgMHhjNGI1YjU3MSwgMHhhYTY2NjZjYyxcbiAgICAweGQ4NDg0ODkwLCAweDA1MDMwMzA2LCAweDAxZjZmNmY3LCAweDEyMGUwZTFjLFxuICAgIDB4YTM2MTYxYzIsIDB4NWYzNTM1NmEsIDB4Zjk1NzU3YWUsIDB4ZDBiOWI5NjksXG4gICAgMHg5MTg2ODYxNywgMHg1OGMxYzE5OSwgMHgyNzFkMWQzYSwgMHhiOTllOWUyNyxcbiAgICAweDM4ZTFlMWQ5LCAweDEzZjhmOGViLCAweGIzOTg5ODJiLCAweDMzMTExMTIyLFxuICAgIDB4YmI2OTY5ZDIsIDB4NzBkOWQ5YTksIDB4ODk4ZThlMDcsIDB4YTc5NDk0MzMsXG4gICAgMHhiNjliOWIyZCwgMHgyMjFlMWUzYywgMHg5Mjg3ODcxNSwgMHgyMGU5ZTljOSxcbiAgICAweDQ5Y2VjZTg3LCAweGZmNTU1NWFhLCAweDc4MjgyODUwLCAweDdhZGZkZmE1LFxuICAgIDB4OGY4YzhjMDMsIDB4ZjhhMWExNTksIDB4ODA4OTg5MDksIDB4MTcwZDBkMWEsXG4gICAgMHhkYWJmYmY2NSwgMHgzMWU2ZTZkNywgMHhjNjQyNDI4NCwgMHhiODY4NjhkMCxcbiAgICAweGMzNDE0MTgyLCAweGIwOTk5OTI5LCAweDc3MmQyZDVhLCAweDExMGYwZjFlLFxuICAgIDB4Y2JiMGIwN2IsIDB4ZmM1NDU0YTgsIDB4ZDZiYmJiNmQsIDB4M2ExNjE2MmNcbl07XG5cbnZhciBUMiA9IFtcbiAgICAweDYzNjNjNmE1LCAweDdjN2NmODg0LCAweDc3NzdlZTk5LCAweDdiN2JmNjhkLFxuICAgIDB4ZjJmMmZmMGQsIDB4NmI2YmQ2YmQsIDB4NmY2ZmRlYjEsIDB4YzVjNTkxNTQsXG4gICAgMHgzMDMwNjA1MCwgMHgwMTAxMDIwMywgMHg2NzY3Y2VhOSwgMHgyYjJiNTY3ZCxcbiAgICAweGZlZmVlNzE5LCAweGQ3ZDdiNTYyLCAweGFiYWI0ZGU2LCAweDc2NzZlYzlhLFxuICAgIDB4Y2FjYThmNDUsIDB4ODI4MjFmOWQsIDB4YzljOTg5NDAsIDB4N2Q3ZGZhODcsXG4gICAgMHhmYWZhZWYxNSwgMHg1OTU5YjJlYiwgMHg0NzQ3OGVjOSwgMHhmMGYwZmIwYixcbiAgICAweGFkYWQ0MWVjLCAweGQ0ZDRiMzY3LCAweGEyYTI1ZmZkLCAweGFmYWY0NWVhLFxuICAgIDB4OWM5YzIzYmYsIDB4YTRhNDUzZjcsIDB4NzI3MmU0OTYsIDB4YzBjMDliNWIsXG4gICAgMHhiN2I3NzVjMiwgMHhmZGZkZTExYywgMHg5MzkzM2RhZSwgMHgyNjI2NGM2YSxcbiAgICAweDM2MzY2YzVhLCAweDNmM2Y3ZTQxLCAweGY3ZjdmNTAyLCAweGNjY2M4MzRmLFxuICAgIDB4MzQzNDY4NWMsIDB4YTVhNTUxZjQsIDB4ZTVlNWQxMzQsIDB4ZjFmMWY5MDgsXG4gICAgMHg3MTcxZTI5MywgMHhkOGQ4YWI3MywgMHgzMTMxNjI1MywgMHgxNTE1MmEzZixcbiAgICAweDA0MDQwODBjLCAweGM3Yzc5NTUyLCAweDIzMjM0NjY1LCAweGMzYzM5ZDVlLFxuICAgIDB4MTgxODMwMjgsIDB4OTY5NjM3YTEsIDB4MDUwNTBhMGYsIDB4OWE5YTJmYjUsXG4gICAgMHgwNzA3MGUwOSwgMHgxMjEyMjQzNiwgMHg4MDgwMWI5YiwgMHhlMmUyZGYzZCxcbiAgICAweGViZWJjZDI2LCAweDI3Mjc0ZTY5LCAweGIyYjI3ZmNkLCAweDc1NzVlYTlmLFxuICAgIDB4MDkwOTEyMWIsIDB4ODM4MzFkOWUsIDB4MmMyYzU4NzQsIDB4MWExYTM0MmUsXG4gICAgMHgxYjFiMzYyZCwgMHg2ZTZlZGNiMiwgMHg1YTVhYjRlZSwgMHhhMGEwNWJmYixcbiAgICAweDUyNTJhNGY2LCAweDNiM2I3NjRkLCAweGQ2ZDZiNzYxLCAweGIzYjM3ZGNlLFxuICAgIDB4MjkyOTUyN2IsIDB4ZTNlM2RkM2UsIDB4MmYyZjVlNzEsIDB4ODQ4NDEzOTcsXG4gICAgMHg1MzUzYTZmNSwgMHhkMWQxYjk2OCwgMHgwMDAwMDAwMCwgMHhlZGVkYzEyYyxcbiAgICAweDIwMjA0MDYwLCAweGZjZmNlMzFmLCAweGIxYjE3OWM4LCAweDViNWJiNmVkLFxuICAgIDB4NmE2YWQ0YmUsIDB4Y2JjYjhkNDYsIDB4YmViZTY3ZDksIDB4MzkzOTcyNGIsXG4gICAgMHg0YTRhOTRkZSwgMHg0YzRjOThkNCwgMHg1ODU4YjBlOCwgMHhjZmNmODU0YSxcbiAgICAweGQwZDBiYjZiLCAweGVmZWZjNTJhLCAweGFhYWE0ZmU1LCAweGZiZmJlZDE2LFxuICAgIDB4NDM0Mzg2YzUsIDB4NGQ0ZDlhZDcsIDB4MzMzMzY2NTUsIDB4ODU4NTExOTQsXG4gICAgMHg0NTQ1OGFjZiwgMHhmOWY5ZTkxMCwgMHgwMjAyMDQwNiwgMHg3ZjdmZmU4MSxcbiAgICAweDUwNTBhMGYwLCAweDNjM2M3ODQ0LCAweDlmOWYyNWJhLCAweGE4YTg0YmUzLFxuICAgIDB4NTE1MWEyZjMsIDB4YTNhMzVkZmUsIDB4NDA0MDgwYzAsIDB4OGY4ZjA1OGEsXG4gICAgMHg5MjkyM2ZhZCwgMHg5ZDlkMjFiYywgMHgzODM4NzA0OCwgMHhmNWY1ZjEwNCxcbiAgICAweGJjYmM2M2RmLCAweGI2YjY3N2MxLCAweGRhZGFhZjc1LCAweDIxMjE0MjYzLFxuICAgIDB4MTAxMDIwMzAsIDB4ZmZmZmU1MWEsIDB4ZjNmM2ZkMGUsIDB4ZDJkMmJmNmQsXG4gICAgMHhjZGNkODE0YywgMHgwYzBjMTgxNCwgMHgxMzEzMjYzNSwgMHhlY2VjYzMyZixcbiAgICAweDVmNWZiZWUxLCAweDk3OTczNWEyLCAweDQ0NDQ4OGNjLCAweDE3MTcyZTM5LFxuICAgIDB4YzRjNDkzNTcsIDB4YTdhNzU1ZjIsIDB4N2U3ZWZjODIsIDB4M2QzZDdhNDcsXG4gICAgMHg2NDY0YzhhYywgMHg1ZDVkYmFlNywgMHgxOTE5MzIyYiwgMHg3MzczZTY5NSxcbiAgICAweDYwNjBjMGEwLCAweDgxODExOTk4LCAweDRmNGY5ZWQxLCAweGRjZGNhMzdmLFxuICAgIDB4MjIyMjQ0NjYsIDB4MmEyYTU0N2UsIDB4OTA5MDNiYWIsIDB4ODg4ODBiODMsXG4gICAgMHg0NjQ2OGNjYSwgMHhlZWVlYzcyOSwgMHhiOGI4NmJkMywgMHgxNDE0MjgzYyxcbiAgICAweGRlZGVhNzc5LCAweDVlNWViY2UyLCAweDBiMGIxNjFkLCAweGRiZGJhZDc2LFxuICAgIDB4ZTBlMGRiM2IsIDB4MzIzMjY0NTYsIDB4M2EzYTc0NGUsIDB4MGEwYTE0MWUsXG4gICAgMHg0OTQ5OTJkYiwgMHgwNjA2MGMwYSwgMHgyNDI0NDg2YywgMHg1YzVjYjhlNCxcbiAgICAweGMyYzI5ZjVkLCAweGQzZDNiZDZlLCAweGFjYWM0M2VmLCAweDYyNjJjNGE2LFxuICAgIDB4OTE5MTM5YTgsIDB4OTU5NTMxYTQsIDB4ZTRlNGQzMzcsIDB4Nzk3OWYyOGIsXG4gICAgMHhlN2U3ZDUzMiwgMHhjOGM4OGI0MywgMHgzNzM3NmU1OSwgMHg2ZDZkZGFiNyxcbiAgICAweDhkOGQwMThjLCAweGQ1ZDViMTY0LCAweDRlNGU5Y2QyLCAweGE5YTk0OWUwLFxuICAgIDB4NmM2Y2Q4YjQsIDB4NTY1NmFjZmEsIDB4ZjRmNGYzMDcsIDB4ZWFlYWNmMjUsXG4gICAgMHg2NTY1Y2FhZiwgMHg3YTdhZjQ4ZSwgMHhhZWFlNDdlOSwgMHgwODA4MTAxOCxcbiAgICAweGJhYmE2ZmQ1LCAweDc4NzhmMDg4LCAweDI1MjU0YTZmLCAweDJlMmU1YzcyLFxuICAgIDB4MWMxYzM4MjQsIDB4YTZhNjU3ZjEsIDB4YjRiNDczYzcsIDB4YzZjNjk3NTEsXG4gICAgMHhlOGU4Y2IyMywgMHhkZGRkYTE3YywgMHg3NDc0ZTg5YywgMHgxZjFmM2UyMSxcbiAgICAweDRiNGI5NmRkLCAweGJkYmQ2MWRjLCAweDhiOGIwZDg2LCAweDhhOGEwZjg1LFxuICAgIDB4NzA3MGUwOTAsIDB4M2UzZTdjNDIsIDB4YjViNTcxYzQsIDB4NjY2NmNjYWEsXG4gICAgMHg0ODQ4OTBkOCwgMHgwMzAzMDYwNSwgMHhmNmY2ZjcwMSwgMHgwZTBlMWMxMixcbiAgICAweDYxNjFjMmEzLCAweDM1MzU2YTVmLCAweDU3NTdhZWY5LCAweGI5Yjk2OWQwLFxuICAgIDB4ODY4NjE3OTEsIDB4YzFjMTk5NTgsIDB4MWQxZDNhMjcsIDB4OWU5ZTI3YjksXG4gICAgMHhlMWUxZDkzOCwgMHhmOGY4ZWIxMywgMHg5ODk4MmJiMywgMHgxMTExMjIzMyxcbiAgICAweDY5NjlkMmJiLCAweGQ5ZDlhOTcwLCAweDhlOGUwNzg5LCAweDk0OTQzM2E3LFxuICAgIDB4OWI5YjJkYjYsIDB4MWUxZTNjMjIsIDB4ODc4NzE1OTIsIDB4ZTllOWM5MjAsXG4gICAgMHhjZWNlODc0OSwgMHg1NTU1YWFmZiwgMHgyODI4NTA3OCwgMHhkZmRmYTU3YSxcbiAgICAweDhjOGMwMzhmLCAweGExYTE1OWY4LCAweDg5ODkwOTgwLCAweDBkMGQxYTE3LFxuICAgIDB4YmZiZjY1ZGEsIDB4ZTZlNmQ3MzEsIDB4NDI0Mjg0YzYsIDB4Njg2OGQwYjgsXG4gICAgMHg0MTQxODJjMywgMHg5OTk5MjliMCwgMHgyZDJkNWE3NywgMHgwZjBmMWUxMSxcbiAgICAweGIwYjA3YmNiLCAweDU0NTRhOGZjLCAweGJiYmI2ZGQ2LCAweDE2MTYyYzNhXG5dO1xuXG52YXIgVDMgPSBbXG4gICAgMHg2M2M2YTU2MywgMHg3Y2Y4ODQ3YywgMHg3N2VlOTk3NywgMHg3YmY2OGQ3YixcbiAgICAweGYyZmYwZGYyLCAweDZiZDZiZDZiLCAweDZmZGViMTZmLCAweGM1OTE1NGM1LFxuICAgIDB4MzA2MDUwMzAsIDB4MDEwMjAzMDEsIDB4NjdjZWE5NjcsIDB4MmI1NjdkMmIsXG4gICAgMHhmZWU3MTlmZSwgMHhkN2I1NjJkNywgMHhhYjRkZTZhYiwgMHg3NmVjOWE3NixcbiAgICAweGNhOGY0NWNhLCAweDgyMWY5ZDgyLCAweGM5ODk0MGM5LCAweDdkZmE4NzdkLFxuICAgIDB4ZmFlZjE1ZmEsIDB4NTliMmViNTksIDB4NDc4ZWM5NDcsIDB4ZjBmYjBiZjAsXG4gICAgMHhhZDQxZWNhZCwgMHhkNGIzNjdkNCwgMHhhMjVmZmRhMiwgMHhhZjQ1ZWFhZixcbiAgICAweDljMjNiZjljLCAweGE0NTNmN2E0LCAweDcyZTQ5NjcyLCAweGMwOWI1YmMwLFxuICAgIDB4Yjc3NWMyYjcsIDB4ZmRlMTFjZmQsIDB4OTMzZGFlOTMsIDB4MjY0YzZhMjYsXG4gICAgMHgzNjZjNWEzNiwgMHgzZjdlNDEzZiwgMHhmN2Y1MDJmNywgMHhjYzgzNGZjYyxcbiAgICAweDM0Njg1YzM0LCAweGE1NTFmNGE1LCAweGU1ZDEzNGU1LCAweGYxZjkwOGYxLFxuICAgIDB4NzFlMjkzNzEsIDB4ZDhhYjczZDgsIDB4MzE2MjUzMzEsIDB4MTUyYTNmMTUsXG4gICAgMHgwNDA4MGMwNCwgMHhjNzk1NTJjNywgMHgyMzQ2NjUyMywgMHhjMzlkNWVjMyxcbiAgICAweDE4MzAyODE4LCAweDk2MzdhMTk2LCAweDA1MGEwZjA1LCAweDlhMmZiNTlhLFxuICAgIDB4MDcwZTA5MDcsIDB4MTIyNDM2MTIsIDB4ODAxYjliODAsIDB4ZTJkZjNkZTIsXG4gICAgMHhlYmNkMjZlYiwgMHgyNzRlNjkyNywgMHhiMjdmY2RiMiwgMHg3NWVhOWY3NSxcbiAgICAweDA5MTIxYjA5LCAweDgzMWQ5ZTgzLCAweDJjNTg3NDJjLCAweDFhMzQyZTFhLFxuICAgIDB4MWIzNjJkMWIsIDB4NmVkY2IyNmUsIDB4NWFiNGVlNWEsIDB4YTA1YmZiYTAsXG4gICAgMHg1MmE0ZjY1MiwgMHgzYjc2NGQzYiwgMHhkNmI3NjFkNiwgMHhiMzdkY2ViMyxcbiAgICAweDI5NTI3YjI5LCAweGUzZGQzZWUzLCAweDJmNWU3MTJmLCAweDg0MTM5Nzg0LFxuICAgIDB4NTNhNmY1NTMsIDB4ZDFiOTY4ZDEsIDB4MDAwMDAwMDAsIDB4ZWRjMTJjZWQsXG4gICAgMHgyMDQwNjAyMCwgMHhmY2UzMWZmYywgMHhiMTc5YzhiMSwgMHg1YmI2ZWQ1YixcbiAgICAweDZhZDRiZTZhLCAweGNiOGQ0NmNiLCAweGJlNjdkOWJlLCAweDM5NzI0YjM5LFxuICAgIDB4NGE5NGRlNGEsIDB4NGM5OGQ0NGMsIDB4NThiMGU4NTgsIDB4Y2Y4NTRhY2YsXG4gICAgMHhkMGJiNmJkMCwgMHhlZmM1MmFlZiwgMHhhYTRmZTVhYSwgMHhmYmVkMTZmYixcbiAgICAweDQzODZjNTQzLCAweDRkOWFkNzRkLCAweDMzNjY1NTMzLCAweDg1MTE5NDg1LFxuICAgIDB4NDU4YWNmNDUsIDB4ZjllOTEwZjksIDB4MDIwNDA2MDIsIDB4N2ZmZTgxN2YsXG4gICAgMHg1MGEwZjA1MCwgMHgzYzc4NDQzYywgMHg5ZjI1YmE5ZiwgMHhhODRiZTNhOCxcbiAgICAweDUxYTJmMzUxLCAweGEzNWRmZWEzLCAweDQwODBjMDQwLCAweDhmMDU4YThmLFxuICAgIDB4OTIzZmFkOTIsIDB4OWQyMWJjOWQsIDB4Mzg3MDQ4MzgsIDB4ZjVmMTA0ZjUsXG4gICAgMHhiYzYzZGZiYywgMHhiNjc3YzFiNiwgMHhkYWFmNzVkYSwgMHgyMTQyNjMyMSxcbiAgICAweDEwMjAzMDEwLCAweGZmZTUxYWZmLCAweGYzZmQwZWYzLCAweGQyYmY2ZGQyLFxuICAgIDB4Y2Q4MTRjY2QsIDB4MGMxODE0MGMsIDB4MTMyNjM1MTMsIDB4ZWNjMzJmZWMsXG4gICAgMHg1ZmJlZTE1ZiwgMHg5NzM1YTI5NywgMHg0NDg4Y2M0NCwgMHgxNzJlMzkxNyxcbiAgICAweGM0OTM1N2M0LCAweGE3NTVmMmE3LCAweDdlZmM4MjdlLCAweDNkN2E0NzNkLFxuICAgIDB4NjRjOGFjNjQsIDB4NWRiYWU3NWQsIDB4MTkzMjJiMTksIDB4NzNlNjk1NzMsXG4gICAgMHg2MGMwYTA2MCwgMHg4MTE5OTg4MSwgMHg0ZjllZDE0ZiwgMHhkY2EzN2ZkYyxcbiAgICAweDIyNDQ2NjIyLCAweDJhNTQ3ZTJhLCAweDkwM2JhYjkwLCAweDg4MGI4Mzg4LFxuICAgIDB4NDY4Y2NhNDYsIDB4ZWVjNzI5ZWUsIDB4Yjg2YmQzYjgsIDB4MTQyODNjMTQsXG4gICAgMHhkZWE3NzlkZSwgMHg1ZWJjZTI1ZSwgMHgwYjE2MWQwYiwgMHhkYmFkNzZkYixcbiAgICAweGUwZGIzYmUwLCAweDMyNjQ1NjMyLCAweDNhNzQ0ZTNhLCAweDBhMTQxZTBhLFxuICAgIDB4NDk5MmRiNDksIDB4MDYwYzBhMDYsIDB4MjQ0ODZjMjQsIDB4NWNiOGU0NWMsXG4gICAgMHhjMjlmNWRjMiwgMHhkM2JkNmVkMywgMHhhYzQzZWZhYywgMHg2MmM0YTY2MixcbiAgICAweDkxMzlhODkxLCAweDk1MzFhNDk1LCAweGU0ZDMzN2U0LCAweDc5ZjI4Yjc5LFxuICAgIDB4ZTdkNTMyZTcsIDB4Yzg4YjQzYzgsIDB4Mzc2ZTU5MzcsIDB4NmRkYWI3NmQsXG4gICAgMHg4ZDAxOGM4ZCwgMHhkNWIxNjRkNSwgMHg0ZTljZDI0ZSwgMHhhOTQ5ZTBhOSxcbiAgICAweDZjZDhiNDZjLCAweDU2YWNmYTU2LCAweGY0ZjMwN2Y0LCAweGVhY2YyNWVhLFxuICAgIDB4NjVjYWFmNjUsIDB4N2FmNDhlN2EsIDB4YWU0N2U5YWUsIDB4MDgxMDE4MDgsXG4gICAgMHhiYTZmZDViYSwgMHg3OGYwODg3OCwgMHgyNTRhNmYyNSwgMHgyZTVjNzIyZSxcbiAgICAweDFjMzgyNDFjLCAweGE2NTdmMWE2LCAweGI0NzNjN2I0LCAweGM2OTc1MWM2LFxuICAgIDB4ZThjYjIzZTgsIDB4ZGRhMTdjZGQsIDB4NzRlODljNzQsIDB4MWYzZTIxMWYsXG4gICAgMHg0Yjk2ZGQ0YiwgMHhiZDYxZGNiZCwgMHg4YjBkODY4YiwgMHg4YTBmODU4YSxcbiAgICAweDcwZTA5MDcwLCAweDNlN2M0MjNlLCAweGI1NzFjNGI1LCAweDY2Y2NhYTY2LFxuICAgIDB4NDg5MGQ4NDgsIDB4MDMwNjA1MDMsIDB4ZjZmNzAxZjYsIDB4MGUxYzEyMGUsXG4gICAgMHg2MWMyYTM2MSwgMHgzNTZhNWYzNSwgMHg1N2FlZjk1NywgMHhiOTY5ZDBiOSxcbiAgICAweDg2MTc5MTg2LCAweGMxOTk1OGMxLCAweDFkM2EyNzFkLCAweDllMjdiOTllLFxuICAgIDB4ZTFkOTM4ZTEsIDB4ZjhlYjEzZjgsIDB4OTgyYmIzOTgsIDB4MTEyMjMzMTEsXG4gICAgMHg2OWQyYmI2OSwgMHhkOWE5NzBkOSwgMHg4ZTA3ODk4ZSwgMHg5NDMzYTc5NCxcbiAgICAweDliMmRiNjliLCAweDFlM2MyMjFlLCAweDg3MTU5Mjg3LCAweGU5YzkyMGU5LFxuICAgIDB4Y2U4NzQ5Y2UsIDB4NTVhYWZmNTUsIDB4Mjg1MDc4MjgsIDB4ZGZhNTdhZGYsXG4gICAgMHg4YzAzOGY4YywgMHhhMTU5ZjhhMSwgMHg4OTA5ODA4OSwgMHgwZDFhMTcwZCxcbiAgICAweGJmNjVkYWJmLCAweGU2ZDczMWU2LCAweDQyODRjNjQyLCAweDY4ZDBiODY4LFxuICAgIDB4NDE4MmMzNDEsIDB4OTkyOWIwOTksIDB4MmQ1YTc3MmQsIDB4MGYxZTExMGYsXG4gICAgMHhiMDdiY2JiMCwgMHg1NGE4ZmM1NCwgMHhiYjZkZDZiYiwgMHgxNjJjM2ExNlxuXTtcblxudmFyIFQ0ID0gW1xuICAgIDB4YzZhNTYzNjMsIDB4Zjg4NDdjN2MsIDB4ZWU5OTc3NzcsIDB4ZjY4ZDdiN2IsXG4gICAgMHhmZjBkZjJmMiwgMHhkNmJkNmI2YiwgMHhkZWIxNmY2ZiwgMHg5MTU0YzVjNSxcbiAgICAweDYwNTAzMDMwLCAweDAyMDMwMTAxLCAweGNlYTk2NzY3LCAweDU2N2QyYjJiLFxuICAgIDB4ZTcxOWZlZmUsIDB4YjU2MmQ3ZDcsIDB4NGRlNmFiYWIsIDB4ZWM5YTc2NzYsXG4gICAgMHg4ZjQ1Y2FjYSwgMHgxZjlkODI4MiwgMHg4OTQwYzljOSwgMHhmYTg3N2Q3ZCxcbiAgICAweGVmMTVmYWZhLCAweGIyZWI1OTU5LCAweDhlYzk0NzQ3LCAweGZiMGJmMGYwLFxuICAgIDB4NDFlY2FkYWQsIDB4YjM2N2Q0ZDQsIDB4NWZmZGEyYTIsIDB4NDVlYWFmYWYsXG4gICAgMHgyM2JmOWM5YywgMHg1M2Y3YTRhNCwgMHhlNDk2NzI3MiwgMHg5YjViYzBjMCxcbiAgICAweDc1YzJiN2I3LCAweGUxMWNmZGZkLCAweDNkYWU5MzkzLCAweDRjNmEyNjI2LFxuICAgIDB4NmM1YTM2MzYsIDB4N2U0MTNmM2YsIDB4ZjUwMmY3ZjcsIDB4ODM0ZmNjY2MsXG4gICAgMHg2ODVjMzQzNCwgMHg1MWY0YTVhNSwgMHhkMTM0ZTVlNSwgMHhmOTA4ZjFmMSxcbiAgICAweGUyOTM3MTcxLCAweGFiNzNkOGQ4LCAweDYyNTMzMTMxLCAweDJhM2YxNTE1LFxuICAgIDB4MDgwYzA0MDQsIDB4OTU1MmM3YzcsIDB4NDY2NTIzMjMsIDB4OWQ1ZWMzYzMsXG4gICAgMHgzMDI4MTgxOCwgMHgzN2ExOTY5NiwgMHgwYTBmMDUwNSwgMHgyZmI1OWE5YSxcbiAgICAweDBlMDkwNzA3LCAweDI0MzYxMjEyLCAweDFiOWI4MDgwLCAweGRmM2RlMmUyLFxuICAgIDB4Y2QyNmViZWIsIDB4NGU2OTI3MjcsIDB4N2ZjZGIyYjIsIDB4ZWE5Zjc1NzUsXG4gICAgMHgxMjFiMDkwOSwgMHgxZDllODM4MywgMHg1ODc0MmMyYywgMHgzNDJlMWExYSxcbiAgICAweDM2MmQxYjFiLCAweGRjYjI2ZTZlLCAweGI0ZWU1YTVhLCAweDViZmJhMGEwLFxuICAgIDB4YTRmNjUyNTIsIDB4NzY0ZDNiM2IsIDB4Yjc2MWQ2ZDYsIDB4N2RjZWIzYjMsXG4gICAgMHg1MjdiMjkyOSwgMHhkZDNlZTNlMywgMHg1ZTcxMmYyZiwgMHgxMzk3ODQ4NCxcbiAgICAweGE2ZjU1MzUzLCAweGI5NjhkMWQxLCAweDAwMDAwMDAwLCAweGMxMmNlZGVkLFxuICAgIDB4NDA2MDIwMjAsIDB4ZTMxZmZjZmMsIDB4NzljOGIxYjEsIDB4YjZlZDViNWIsXG4gICAgMHhkNGJlNmE2YSwgMHg4ZDQ2Y2JjYiwgMHg2N2Q5YmViZSwgMHg3MjRiMzkzOSxcbiAgICAweDk0ZGU0YTRhLCAweDk4ZDQ0YzRjLCAweGIwZTg1ODU4LCAweDg1NGFjZmNmLFxuICAgIDB4YmI2YmQwZDAsIDB4YzUyYWVmZWYsIDB4NGZlNWFhYWEsIDB4ZWQxNmZiZmIsXG4gICAgMHg4NmM1NDM0MywgMHg5YWQ3NGQ0ZCwgMHg2NjU1MzMzMywgMHgxMTk0ODU4NSxcbiAgICAweDhhY2Y0NTQ1LCAweGU5MTBmOWY5LCAweDA0MDYwMjAyLCAweGZlODE3ZjdmLFxuICAgIDB4YTBmMDUwNTAsIDB4Nzg0NDNjM2MsIDB4MjViYTlmOWYsIDB4NGJlM2E4YTgsXG4gICAgMHhhMmYzNTE1MSwgMHg1ZGZlYTNhMywgMHg4MGMwNDA0MCwgMHgwNThhOGY4ZixcbiAgICAweDNmYWQ5MjkyLCAweDIxYmM5ZDlkLCAweDcwNDgzODM4LCAweGYxMDRmNWY1LFxuICAgIDB4NjNkZmJjYmMsIDB4NzdjMWI2YjYsIDB4YWY3NWRhZGEsIDB4NDI2MzIxMjEsXG4gICAgMHgyMDMwMTAxMCwgMHhlNTFhZmZmZiwgMHhmZDBlZjNmMywgMHhiZjZkZDJkMixcbiAgICAweDgxNGNjZGNkLCAweDE4MTQwYzBjLCAweDI2MzUxMzEzLCAweGMzMmZlY2VjLFxuICAgIDB4YmVlMTVmNWYsIDB4MzVhMjk3OTcsIDB4ODhjYzQ0NDQsIDB4MmUzOTE3MTcsXG4gICAgMHg5MzU3YzRjNCwgMHg1NWYyYTdhNywgMHhmYzgyN2U3ZSwgMHg3YTQ3M2QzZCxcbiAgICAweGM4YWM2NDY0LCAweGJhZTc1ZDVkLCAweDMyMmIxOTE5LCAweGU2OTU3MzczLFxuICAgIDB4YzBhMDYwNjAsIDB4MTk5ODgxODEsIDB4OWVkMTRmNGYsIDB4YTM3ZmRjZGMsXG4gICAgMHg0NDY2MjIyMiwgMHg1NDdlMmEyYSwgMHgzYmFiOTA5MCwgMHgwYjgzODg4OCxcbiAgICAweDhjY2E0NjQ2LCAweGM3MjllZWVlLCAweDZiZDNiOGI4LCAweDI4M2MxNDE0LFxuICAgIDB4YTc3OWRlZGUsIDB4YmNlMjVlNWUsIDB4MTYxZDBiMGIsIDB4YWQ3NmRiZGIsXG4gICAgMHhkYjNiZTBlMCwgMHg2NDU2MzIzMiwgMHg3NDRlM2EzYSwgMHgxNDFlMGEwYSxcbiAgICAweDkyZGI0OTQ5LCAweDBjMGEwNjA2LCAweDQ4NmMyNDI0LCAweGI4ZTQ1YzVjLFxuICAgIDB4OWY1ZGMyYzIsIDB4YmQ2ZWQzZDMsIDB4NDNlZmFjYWMsIDB4YzRhNjYyNjIsXG4gICAgMHgzOWE4OTE5MSwgMHgzMWE0OTU5NSwgMHhkMzM3ZTRlNCwgMHhmMjhiNzk3OSxcbiAgICAweGQ1MzJlN2U3LCAweDhiNDNjOGM4LCAweDZlNTkzNzM3LCAweGRhYjc2ZDZkLFxuICAgIDB4MDE4YzhkOGQsIDB4YjE2NGQ1ZDUsIDB4OWNkMjRlNGUsIDB4NDllMGE5YTksXG4gICAgMHhkOGI0NmM2YywgMHhhY2ZhNTY1NiwgMHhmMzA3ZjRmNCwgMHhjZjI1ZWFlYSxcbiAgICAweGNhYWY2NTY1LCAweGY0OGU3YTdhLCAweDQ3ZTlhZWFlLCAweDEwMTgwODA4LFxuICAgIDB4NmZkNWJhYmEsIDB4ZjA4ODc4NzgsIDB4NGE2ZjI1MjUsIDB4NWM3MjJlMmUsXG4gICAgMHgzODI0MWMxYywgMHg1N2YxYTZhNiwgMHg3M2M3YjRiNCwgMHg5NzUxYzZjNixcbiAgICAweGNiMjNlOGU4LCAweGExN2NkZGRkLCAweGU4OWM3NDc0LCAweDNlMjExZjFmLFxuICAgIDB4OTZkZDRiNGIsIDB4NjFkY2JkYmQsIDB4MGQ4NjhiOGIsIDB4MGY4NThhOGEsXG4gICAgMHhlMDkwNzA3MCwgMHg3YzQyM2UzZSwgMHg3MWM0YjViNSwgMHhjY2FhNjY2NixcbiAgICAweDkwZDg0ODQ4LCAweDA2MDUwMzAzLCAweGY3MDFmNmY2LCAweDFjMTIwZTBlLFxuICAgIDB4YzJhMzYxNjEsIDB4NmE1ZjM1MzUsIDB4YWVmOTU3NTcsIDB4NjlkMGI5YjksXG4gICAgMHgxNzkxODY4NiwgMHg5OTU4YzFjMSwgMHgzYTI3MWQxZCwgMHgyN2I5OWU5ZSxcbiAgICAweGQ5MzhlMWUxLCAweGViMTNmOGY4LCAweDJiYjM5ODk4LCAweDIyMzMxMTExLFxuICAgIDB4ZDJiYjY5NjksIDB4YTk3MGQ5ZDksIDB4MDc4OThlOGUsIDB4MzNhNzk0OTQsXG4gICAgMHgyZGI2OWI5YiwgMHgzYzIyMWUxZSwgMHgxNTkyODc4NywgMHhjOTIwZTllOSxcbiAgICAweDg3NDljZWNlLCAweGFhZmY1NTU1LCAweDUwNzgyODI4LCAweGE1N2FkZmRmLFxuICAgIDB4MDM4ZjhjOGMsIDB4NTlmOGExYTEsIDB4MDk4MDg5ODksIDB4MWExNzBkMGQsXG4gICAgMHg2NWRhYmZiZiwgMHhkNzMxZTZlNiwgMHg4NGM2NDI0MiwgMHhkMGI4Njg2OCxcbiAgICAweDgyYzM0MTQxLCAweDI5YjA5OTk5LCAweDVhNzcyZDJkLCAweDFlMTEwZjBmLFxuICAgIDB4N2JjYmIwYjAsIDB4YThmYzU0NTQsIDB4NmRkNmJiYmIsIDB4MmMzYTE2MTZcbl07XG5cbmZ1bmN0aW9uIEIwKHgpIHtcbiAgcmV0dXJuICh4ICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gQjEoeCkge1xuICByZXR1cm4gKCh4ID4+IDgpICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gQjIoeCkge1xuICByZXR1cm4gKCh4ID4+IDE2KSAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEIzKHgpIHtcbiAgcmV0dXJuICgoeCA+PiAyNCkgJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBGMSh4MCwgeDEsIHgyLCB4Mykge1xuICByZXR1cm4gQjEoVDFbeDAgJiAyNTVdKSB8IChCMShUMVsoeDEgPj4gOCkgJiAyNTVdKSA8PCA4KSB8IChCMShUMVsoeDIgPj4gMTYpICYgMjU1XSkgPDwgMTYpIHwgKEIxKFQxW3gzID4+PiAyNF0pIDw8XG4gICAgMjQpO1xufVxuXG5mdW5jdGlvbiBwYWNrQnl0ZXMob2N0ZXRzKSB7XG4gIHZhciBpLCBqO1xuICB2YXIgbGVuID0gb2N0ZXRzLmxlbmd0aDtcbiAgdmFyIGIgPSBuZXcgQXJyYXkobGVuIC8gNCk7XG5cbiAgaWYgKCFvY3RldHMgfHwgbGVuICUgNCkgcmV0dXJuO1xuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBqIDwgbGVuOyBqICs9IDQpXG4gICAgYltpKytdID0gb2N0ZXRzW2pdIHwgKG9jdGV0c1tqICsgMV0gPDwgOCkgfCAob2N0ZXRzW2ogKyAyXSA8PCAxNikgfCAob2N0ZXRzW2ogKyAzXSA8PCAyNCk7XG5cbiAgcmV0dXJuIGI7XG59XG5cbmZ1bmN0aW9uIHVucGFja0J5dGVzKHBhY2tlZCkge1xuICB2YXIgajtcbiAgdmFyIGkgPSAwLFxuICAgIGwgPSBwYWNrZWQubGVuZ3RoO1xuICB2YXIgciA9IG5ldyBBcnJheShsICogNCk7XG5cbiAgZm9yIChqID0gMDsgaiA8IGw7IGorKykge1xuICAgIHJbaSsrXSA9IEIwKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjEocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMihwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIzKHBhY2tlZFtqXSk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgbWF4a2MgPSA4O1xudmFyIG1heHJrID0gMTQ7XG5cbmZ1bmN0aW9uIGtleUV4cGFuc2lvbihrZXkpIHtcbiAgdmFyIGtjLCBpLCBqLCByLCB0O1xuICB2YXIgcm91bmRzO1xuICB2YXIga2V5U2NoZWQgPSBuZXcgQXJyYXkobWF4cmsgKyAxKTtcbiAgdmFyIGtleWxlbiA9IGtleS5sZW5ndGg7XG4gIHZhciBrID0gbmV3IEFycmF5KG1heGtjKTtcbiAgdmFyIHRrID0gbmV3IEFycmF5KG1heGtjKTtcbiAgdmFyIHJjb25wb2ludGVyID0gMDtcblxuICBpZiAoa2V5bGVuID09IDE2KSB7XG4gICAgcm91bmRzID0gMTA7XG4gICAga2MgPSA0O1xuICB9IGVsc2UgaWYgKGtleWxlbiA9PSAyNCkge1xuICAgIHJvdW5kcyA9IDEyO1xuICAgIGtjID0gNjtcbiAgfSBlbHNlIGlmIChrZXlsZW4gPT0gMzIpIHtcbiAgICByb3VuZHMgPSAxNDtcbiAgICBrYyA9IDg7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleS1sZW5ndGggZm9yIEFFUyBrZXk6JyArIGtleWxlbik7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgbWF4cmsgKyAxOyBpKyspIGtleVNjaGVkW2ldID0gbmV3IEFycmF5KDQpO1xuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBqIDwga2V5bGVuOyBqKyssIGkgKz0gNClcbiAgICBrW2pdID0ga2V5LmNoYXJDb2RlQXQoaSkgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpIHwgKGtleS5jaGFyQ29kZUF0KGkgKyAyKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDMpIDw8XG4gICAgICAyNCk7XG5cbiAgZm9yIChqID0ga2MgLSAxOyBqID49IDA7IGotLSkgdGtbal0gPSBrW2pdO1xuXG4gIHIgPSAwO1xuICB0ID0gMDtcbiAgZm9yIChqID0gMDtcbiAgKGogPCBrYykgJiYgKHIgPCByb3VuZHMgKyAxKTspIHtcbiAgICBmb3IgKDtcbiAgICAoaiA8IGtjKSAmJiAodCA8IDQpOyBqKyssIHQrKykge1xuICAgICAga2V5U2NoZWRbcl1bdF0gPSB0a1tqXTtcbiAgICB9XG4gICAgaWYgKHQgPT0gNCkge1xuICAgICAgcisrO1xuICAgICAgdCA9IDA7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKHIgPCByb3VuZHMgKyAxKSB7XG4gICAgdmFyIHRlbXAgPSB0a1trYyAtIDFdO1xuXG4gICAgdGtbMF0gXj0gU1tCMSh0ZW1wKV0gfCAoU1tCMih0ZW1wKV0gPDwgOCkgfCAoU1tCMyh0ZW1wKV0gPDwgMTYpIHwgKFNbQjAodGVtcCldIDw8IDI0KTtcbiAgICB0a1swXSBePSBSY29uW3Jjb25wb2ludGVyKytdO1xuXG4gICAgaWYgKGtjICE9IDgpIHtcbiAgICAgIGZvciAoaiA9IDE7IGogPCBrYzsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaiA9IDE7IGogPCBrYyAvIDI7IGorKykgdGtbal0gXj0gdGtbaiAtIDFdO1xuXG4gICAgICB0ZW1wID0gdGtba2MgLyAyIC0gMV07XG4gICAgICB0a1trYyAvIDJdIF49IFNbQjAodGVtcCldIHwgKFNbQjEodGVtcCldIDw8IDgpIHwgKFNbQjIodGVtcCldIDw8IDE2KSB8IChTW0IzKHRlbXApXSA8PCAyNCk7XG5cbiAgICAgIGZvciAoaiA9IGtjIC8gMiArIDE7IGogPCBrYzsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG4gICAgfVxuXG4gICAgZm9yIChqID0gMDtcbiAgICAoaiA8IGtjKSAmJiAociA8IHJvdW5kcyArIDEpOykge1xuICAgICAgZm9yICg7XG4gICAgICAoaiA8IGtjKSAmJiAodCA8IDQpOyBqKyssIHQrKykge1xuICAgICAgICBrZXlTY2hlZFtyXVt0XSA9IHRrW2pdO1xuICAgICAgfVxuICAgICAgaWYgKHQgPT0gNCkge1xuICAgICAgICByKys7XG4gICAgICAgIHQgPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB0aGlzLnJvdW5kcyA9IHJvdW5kcztcbiAgdGhpcy5yayA9IGtleVNjaGVkO1xuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gQUVTZW5jcnlwdChibG9jaywgY3R4KSB7XG4gIHZhciByO1xuICB2YXIgdDAsIHQxLCB0MiwgdDM7XG5cbiAgdmFyIGIgPSBwYWNrQnl0ZXMoYmxvY2spO1xuICB2YXIgcm91bmRzID0gY3R4LnJvdW5kcztcbiAgdmFyIGIwID0gYlswXTtcbiAgdmFyIGIxID0gYlsxXTtcbiAgdmFyIGIyID0gYlsyXTtcbiAgdmFyIGIzID0gYlszXTtcblxuICBmb3IgKHIgPSAwOyByIDwgcm91bmRzIC0gMTsgcisrKSB7XG4gICAgdDAgPSBiMCBeIGN0eC5ya1tyXVswXTtcbiAgICB0MSA9IGIxIF4gY3R4LnJrW3JdWzFdO1xuICAgIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gICAgdDMgPSBiMyBeIGN0eC5ya1tyXVszXTtcblxuICAgIGIwID0gVDFbdDAgJiAyNTVdIF4gVDJbKHQxID4+IDgpICYgMjU1XSBeIFQzWyh0MiA+PiAxNikgJiAyNTVdIF4gVDRbdDMgPj4+IDI0XTtcbiAgICBiMSA9IFQxW3QxICYgMjU1XSBeIFQyWyh0MiA+PiA4KSAmIDI1NV0gXiBUM1sodDMgPj4gMTYpICYgMjU1XSBeIFQ0W3QwID4+PiAyNF07XG4gICAgYjIgPSBUMVt0MiAmIDI1NV0gXiBUMlsodDMgPj4gOCkgJiAyNTVdIF4gVDNbKHQwID4+IDE2KSAmIDI1NV0gXiBUNFt0MSA+Pj4gMjRdO1xuICAgIGIzID0gVDFbdDMgJiAyNTVdIF4gVDJbKHQwID4+IDgpICYgMjU1XSBeIFQzWyh0MSA+PiAxNikgJiAyNTVdIF4gVDRbdDIgPj4+IDI0XTtcbiAgfVxuXG4gIC8vIGxhc3Qgcm91bmQgaXMgc3BlY2lhbFxuICByID0gcm91bmRzIC0gMTtcblxuICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdO1xuICB0MSA9IGIxIF4gY3R4LnJrW3JdWzFdO1xuICB0MiA9IGIyIF4gY3R4LnJrW3JdWzJdO1xuICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdO1xuXG4gIGJbMF0gPSBGMSh0MCwgdDEsIHQyLCB0MykgXiBjdHgucmtbcm91bmRzXVswXTtcbiAgYlsxXSA9IEYxKHQxLCB0MiwgdDMsIHQwKSBeIGN0eC5ya1tyb3VuZHNdWzFdO1xuICBiWzJdID0gRjEodDIsIHQzLCB0MCwgdDEpIF4gY3R4LnJrW3JvdW5kc11bMl07XG4gIGJbM10gPSBGMSh0MywgdDAsIHQxLCB0MikgXiBjdHgucmtbcm91bmRzXVszXTtcblxuICByZXR1cm4gdW5wYWNrQnl0ZXMoYik7XG59XG5cbmZ1bmN0aW9uIG1ha2VDbGFzcyhsZW5ndGgpIHtcblxuICB2YXIgYyA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHRoaXMua2V5ID0ga2V5RXhwYW5zaW9uKGtleSk7XG5cbiAgICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgICAgcmV0dXJuIEFFU2VuY3J5cHQoYmxvY2ssIHRoaXMua2V5KTtcbiAgICB9XG4gIH1cblxuICBjLmJsb2NrU2l6ZSA9IGMucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDE2O1xuICBjLmtleVNpemUgPSBjLnByb3RvdHlwZS5rZXlTaXplID0gbGVuZ3RoIC8gODtcblxuICByZXR1cm4gYztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7fVxuXG52YXIgdHlwZXMgPSBbMTI4LCAxOTIsIDI1Nl07XG5cbmZvciAodmFyIGkgaW4gdHlwZXMpIHtcbiAgbW9kdWxlLmV4cG9ydHNbdHlwZXNbaV1dID0gbWFrZUNsYXNzKHR5cGVzW2ldKTtcbn1cbiIsIi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogT3JpZ2luYWxseSB3cml0dGVuIGJ5IG5rbGVpbiBzb2Z0d2FyZSAobmtsZWluLmNvbSlcbiAqL1xuXG4vKipcbiAqICBAbW9kdWxlIGNyeXB0by9jaXBoZXIvYmxvd2Zpc2hcbiAqL1xuXG4vKiBcbiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gYmFzZWQgb24gQnJ1Y2UgU2NobmVpZXIncyByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24uXG4gKlxuICpcbiAqIFRoZSBjb25zdHJ1Y3RvciBkb2Vzbid0IGRvIG11Y2ggb2YgYW55dGhpbmcuICBJdCdzIGp1c3QgaGVyZVxuICogc28gd2UgY2FuIHN0YXJ0IGRlZmluaW5nIHByb3BlcnRpZXMgYW5kIG1ldGhvZHMgYW5kIHN1Y2guXG4gKi9cbmZ1bmN0aW9uIEJsb3dmaXNoKCkge307XG5cbi8qXG4gKiBEZWNsYXJlIHRoZSBibG9jayBzaXplIHNvIHRoYXQgcHJvdG9jb2xzIGtub3cgd2hhdCBzaXplXG4gKiBJbml0aWFsaXphdGlvbiBWZWN0b3IgKElWKSB0aGV5IHdpbGwgbmVlZC5cbiAqL1xuQmxvd2Zpc2gucHJvdG90eXBlLkJMT0NLU0laRSA9IDg7XG5cbi8qXG4gKiBUaGVzZSBhcmUgdGhlIGRlZmF1bHQgU0JPWEVTLlxuICovXG5CbG93ZmlzaC5wcm90b3R5cGUuU0JPWEVTID0gW1xuICBbXG4gICAgICAweGQxMzEwYmE2LCAweDk4ZGZiNWFjLCAweDJmZmQ3MmRiLCAweGQwMWFkZmI3LCAweGI4ZTFhZmVkLCAweDZhMjY3ZTk2LFxuICAgICAgMHhiYTdjOTA0NSwgMHhmMTJjN2Y5OSwgMHgyNGExOTk0NywgMHhiMzkxNmNmNywgMHgwODAxZjJlMiwgMHg4NThlZmMxNixcbiAgICAgIDB4NjM2OTIwZDgsIDB4NzE1NzRlNjksIDB4YTQ1OGZlYTMsIDB4ZjQ5MzNkN2UsIDB4MGQ5NTc0OGYsIDB4NzI4ZWI2NTgsXG4gICAgICAweDcxOGJjZDU4LCAweDgyMTU0YWVlLCAweDdiNTRhNDFkLCAweGMyNWE1OWI1LCAweDljMzBkNTM5LCAweDJhZjI2MDEzLFxuICAgICAgMHhjNWQxYjAyMywgMHgyODYwODVmMCwgMHhjYTQxNzkxOCwgMHhiOGRiMzhlZiwgMHg4ZTc5ZGNiMCwgMHg2MDNhMTgwZSxcbiAgICAgIDB4NmM5ZTBlOGIsIDB4YjAxZThhM2UsIDB4ZDcxNTc3YzEsIDB4YmQzMTRiMjcsIDB4NzhhZjJmZGEsIDB4NTU2MDVjNjAsXG4gICAgICAweGU2NTUyNWYzLCAweGFhNTVhYjk0LCAweDU3NDg5ODYyLCAweDYzZTgxNDQwLCAweDU1Y2EzOTZhLCAweDJhYWIxMGI2LFxuICAgICAgMHhiNGNjNWMzNCwgMHgxMTQxZThjZSwgMHhhMTU0ODZhZiwgMHg3YzcyZTk5MywgMHhiM2VlMTQxMSwgMHg2MzZmYmMyYSxcbiAgICAgIDB4MmJhOWM1NWQsIDB4NzQxODMxZjYsIDB4Y2U1YzNlMTYsIDB4OWI4NzkzMWUsIDB4YWZkNmJhMzMsIDB4NmMyNGNmNWMsXG4gICAgICAweDdhMzI1MzgxLCAweDI4OTU4Njc3LCAweDNiOGY0ODk4LCAweDZiNGJiOWFmLCAweGM0YmZlODFiLCAweDY2MjgyMTkzLFxuICAgICAgMHg2MWQ4MDljYywgMHhmYjIxYTk5MSwgMHg0ODdjYWM2MCwgMHg1ZGVjODAzMiwgMHhlZjg0NWQ1ZCwgMHhlOTg1NzViMSxcbiAgICAgIDB4ZGMyNjIzMDIsIDB4ZWI2NTFiODgsIDB4MjM4OTNlODEsIDB4ZDM5NmFjYzUsIDB4MGY2ZDZmZjMsIDB4ODNmNDQyMzksXG4gICAgICAweDJlMGI0NDgyLCAweGE0ODQyMDA0LCAweDY5YzhmMDRhLCAweDllMWY5YjVlLCAweDIxYzY2ODQyLCAweGY2ZTk2YzlhLFxuICAgICAgMHg2NzBjOWM2MSwgMHhhYmQzODhmMCwgMHg2YTUxYTBkMiwgMHhkODU0MmY2OCwgMHg5NjBmYTcyOCwgMHhhYjUxMzNhMyxcbiAgICAgIDB4NmVlZjBiNmMsIDB4MTM3YTNiZTQsIDB4YmEzYmYwNTAsIDB4N2VmYjJhOTgsIDB4YTFmMTY1MWQsIDB4MzlhZjAxNzYsXG4gICAgICAweDY2Y2E1OTNlLCAweDgyNDMwZTg4LCAweDhjZWU4NjE5LCAweDQ1NmY5ZmI0LCAweDdkODRhNWMzLCAweDNiOGI1ZWJlLFxuICAgICAgMHhlMDZmNzVkOCwgMHg4NWMxMjA3MywgMHg0MDFhNDQ5ZiwgMHg1NmMxNmFhNiwgMHg0ZWQzYWE2MiwgMHgzNjNmNzcwNixcbiAgICAgIDB4MWJmZWRmNzIsIDB4NDI5YjAyM2QsIDB4MzdkMGQ3MjQsIDB4ZDAwYTEyNDgsIDB4ZGIwZmVhZDMsIDB4NDlmMWMwOWIsXG4gICAgICAweDA3NTM3MmM5LCAweDgwOTkxYjdiLCAweDI1ZDQ3OWQ4LCAweGY2ZThkZWY3LCAweGUzZmU1MDFhLCAweGI2Nzk0YzNiLFxuICAgICAgMHg5NzZjZTBiZCwgMHgwNGMwMDZiYSwgMHhjMWE5NGZiNiwgMHg0MDlmNjBjNCwgMHg1ZTVjOWVjMiwgMHgxOTZhMjQ2MyxcbiAgICAgIDB4NjhmYjZmYWYsIDB4M2U2YzUzYjUsIDB4MTMzOWIyZWIsIDB4M2I1MmVjNmYsIDB4NmRmYzUxMWYsIDB4OWIzMDk1MmMsXG4gICAgICAweGNjODE0NTQ0LCAweGFmNWViZDA5LCAweGJlZTNkMDA0LCAweGRlMzM0YWZkLCAweDY2MGYyODA3LCAweDE5MmU0YmIzLFxuICAgICAgMHhjMGNiYTg1NywgMHg0NWM4NzQwZiwgMHhkMjBiNWYzOSwgMHhiOWQzZmJkYiwgMHg1NTc5YzBiZCwgMHgxYTYwMzIwYSxcbiAgICAgIDB4ZDZhMTAwYzYsIDB4NDAyYzcyNzksIDB4Njc5ZjI1ZmUsIDB4ZmIxZmEzY2MsIDB4OGVhNWU5ZjgsIDB4ZGIzMjIyZjgsXG4gICAgICAweDNjNzUxNmRmLCAweGZkNjE2YjE1LCAweDJmNTAxZWM4LCAweGFkMDU1MmFiLCAweDMyM2RiNWZhLCAweGZkMjM4NzYwLFxuICAgICAgMHg1MzMxN2I0OCwgMHgzZTAwZGY4MiwgMHg5ZTVjNTdiYiwgMHhjYTZmOGNhMCwgMHgxYTg3NTYyZSwgMHhkZjE3NjlkYixcbiAgICAgIDB4ZDU0MmE4ZjYsIDB4Mjg3ZWZmYzMsIDB4YWM2NzMyYzYsIDB4OGM0ZjU1NzMsIDB4Njk1YjI3YjAsIDB4YmJjYTU4YzgsXG4gICAgICAweGUxZmZhMzVkLCAweGI4ZjAxMWEwLCAweDEwZmEzZDk4LCAweGZkMjE4M2I4LCAweDRhZmNiNTZjLCAweDJkZDFkMzViLFxuICAgICAgMHg5YTUzZTQ3OSwgMHhiNmY4NDU2NSwgMHhkMjhlNDliYywgMHg0YmZiOTc5MCwgMHhlMWRkZjJkYSwgMHhhNGNiN2UzMyxcbiAgICAgIDB4NjJmYjEzNDEsIDB4Y2VlNGM2ZTgsIDB4ZWYyMGNhZGEsIDB4MzY3NzRjMDEsIDB4ZDA3ZTllZmUsIDB4MmJmMTFmYjQsXG4gICAgICAweDk1ZGJkYTRkLCAweGFlOTA5MTk4LCAweGVhYWQ4ZTcxLCAweDZiOTNkNWEwLCAweGQwOGVkMWQwLCAweGFmYzcyNWUwLFxuICAgICAgMHg4ZTNjNWIyZiwgMHg4ZTc1OTRiNywgMHg4ZmY2ZTJmYiwgMHhmMjEyMmI2NCwgMHg4ODg4YjgxMiwgMHg5MDBkZjAxYyxcbiAgICAgIDB4NGZhZDVlYTAsIDB4Njg4ZmMzMWMsIDB4ZDFjZmYxOTEsIDB4YjNhOGMxYWQsIDB4MmYyZjIyMTgsIDB4YmUwZTE3NzcsXG4gICAgICAweGVhNzUyZGZlLCAweDhiMDIxZmExLCAweGU1YTBjYzBmLCAweGI1NmY3NGU4LCAweDE4YWNmM2Q2LCAweGNlODllMjk5LFxuICAgICAgMHhiNGE4NGZlMCwgMHhmZDEzZTBiNywgMHg3Y2M0M2I4MSwgMHhkMmFkYThkOSwgMHgxNjVmYTI2NiwgMHg4MDk1NzcwNSxcbiAgICAgIDB4OTNjYzczMTQsIDB4MjExYTE0NzcsIDB4ZTZhZDIwNjUsIDB4NzdiNWZhODYsIDB4Yzc1NDQyZjUsIDB4ZmI5ZDM1Y2YsXG4gICAgICAweGViY2RhZjBjLCAweDdiM2U4OWEwLCAweGQ2NDExYmQzLCAweGFlMWU3ZTQ5LCAweDAwMjUwZTJkLCAweDIwNzFiMzVlLFxuICAgICAgMHgyMjY4MDBiYiwgMHg1N2I4ZTBhZiwgMHgyNDY0MzY5YiwgMHhmMDA5YjkxZSwgMHg1NTYzOTExZCwgMHg1OWRmYTZhYSxcbiAgICAgIDB4NzhjMTQzODksIDB4ZDk1YTUzN2YsIDB4MjA3ZDViYTIsIDB4MDJlNWI5YzUsIDB4ODMyNjAzNzYsIDB4NjI5NWNmYTksXG4gICAgICAweDExYzgxOTY4LCAweDRlNzM0YTQxLCAweGIzNDcyZGNhLCAweDdiMTRhOTRhLCAweDFiNTEwMDUyLCAweDlhNTMyOTE1LFxuICAgICAgMHhkNjBmNTczZiwgMHhiYzliYzZlNCwgMHgyYjYwYTQ3NiwgMHg4MWU2NzQwMCwgMHgwOGJhNmZiNSwgMHg1NzFiZTkxZixcbiAgICAgIDB4ZjI5NmVjNmIsIDB4MmEwZGQ5MTUsIDB4YjY2MzY1MjEsIDB4ZTdiOWY5YjYsIDB4ZmYzNDA1MmUsIDB4YzU4NTU2NjQsXG4gICAgICAweDUzYjAyZDVkLCAweGE5OWY4ZmExLCAweDA4YmE0Nzk5LCAweDZlODUwNzZhXG4gIF0sXG4gIFtcbiAgICAgIDB4NGI3YTcwZTksIDB4YjViMzI5NDQsIDB4ZGI3NTA5MmUsIDB4YzQxOTI2MjMsIDB4YWQ2ZWE2YjAsIDB4NDlhN2RmN2QsXG4gICAgICAweDljZWU2MGI4LCAweDhmZWRiMjY2LCAweGVjYWE4YzcxLCAweDY5OWExN2ZmLCAweDU2NjQ1MjZjLCAweGMyYjE5ZWUxLFxuICAgICAgMHgxOTM2MDJhNSwgMHg3NTA5NGMyOSwgMHhhMDU5MTM0MCwgMHhlNDE4M2EzZSwgMHgzZjU0OTg5YSwgMHg1YjQyOWQ2NSxcbiAgICAgIDB4NmI4ZmU0ZDYsIDB4OTlmNzNmZDYsIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsXG4gICAgICAweDRjZGQyMDg2LCAweDg0NzBlYjI2LCAweDYzODJlOWM2LCAweDAyMWVjYzVlLCAweDA5Njg2YjNmLCAweDNlYmFlZmM5LFxuICAgICAgMHgzYzk3MTgxNCwgMHg2YjZhNzBhMSwgMHg2ODdmMzU4NCwgMHg1MmEwZTI4NiwgMHhiNzljNTMwNSwgMHhhYTUwMDczNyxcbiAgICAgIDB4M2UwNzg0MWMsIDB4N2ZkZWFlNWMsIDB4OGU3ZDQ0ZWMsIDB4NTcxNmYyYjgsIDB4YjAzYWRhMzcsIDB4ZjA1MDBjMGQsXG4gICAgICAweGYwMWMxZjA0LCAweDAyMDBiM2ZmLCAweGFlMGNmNTFhLCAweDNjYjU3NGIyLCAweDI1ODM3YTU4LCAweGRjMDkyMWJkLFxuICAgICAgMHhkMTkxMTNmOSwgMHg3Y2E5MmZmNiwgMHg5NDMyNDc3MywgMHgyMmY1NDcwMSwgMHgzYWU1ZTU4MSwgMHgzN2MyZGFkYyxcbiAgICAgIDB4YzhiNTc2MzQsIDB4OWFmM2RkYTcsIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsXG4gICAgICAweGUyMzhjZDk5LCAweDNiZWEwZTJmLCAweDMyODBiYmExLCAweDE4M2ViMzMxLCAweDRlNTQ4YjM4LCAweDRmNmRiOTA4LFxuICAgICAgMHg2ZjQyMGQwMywgMHhmNjBhMDRiZiwgMHgyY2I4MTI5MCwgMHgyNDk3N2M3OSwgMHg1Njc5YjA3MiwgMHhiY2FmODlhZixcbiAgICAgIDB4ZGU5YTc3MWYsIDB4ZDk5MzA4MTAsIDB4YjM4YmFlMTIsIDB4ZGNjZjNmMmUsIDB4NTUxMjcyMWYsIDB4MmU2YjcxMjQsXG4gICAgICAweDUwMWFkZGU2LCAweDlmODRjZDg3LCAweDdhNTg0NzE4LCAweDc0MDhkYTE3LCAweGJjOWY5YWJjLCAweGU5NGI3ZDhjLFxuICAgICAgMHhlYzdhZWMzYSwgMHhkYjg1MWRmYSwgMHg2MzA5NDM2NiwgMHhjNDY0YzNkMiwgMHhlZjFjMTg0NywgMHgzMjE1ZDkwOCxcbiAgICAgIDB4ZGQ0MzNiMzcsIDB4MjRjMmJhMTYsIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsXG4gICAgICAweDcxZGZmODllLCAweDEwMzE0ZTU1LCAweDgxYWM3N2Q2LCAweDVmMTExOTliLCAweDA0MzU1NmYxLCAweGQ3YTNjNzZiLFxuICAgICAgMHgzYzExMTgzYiwgMHg1OTI0YTUwOSwgMHhmMjhmZTZlZCwgMHg5N2YxZmJmYSwgMHg5ZWJhYmYyYywgMHgxZTE1M2M2ZSxcbiAgICAgIDB4ODZlMzQ1NzAsIDB4ZWFlOTZmYjEsIDB4ODYwZTVlMGEsIDB4NWEzZTJhYjMsIDB4NzcxZmU3MWMsIDB4NGUzZDA2ZmEsXG4gICAgICAweDI5NjVkY2I5LCAweDk5ZTcxZDBmLCAweDgwM2U4OWQ2LCAweDUyNjZjODI1LCAweDJlNGNjOTc4LCAweDljMTBiMzZhLFxuICAgICAgMHhjNjE1MGViYSwgMHg5NGUyZWE3OCwgMHhhNWZjM2M1MywgMHgxZTBhMmRmNCwgMHhmMmY3NGVhNywgMHgzNjFkMmIzZCxcbiAgICAgIDB4MTkzOTI2MGYsIDB4MTljMjc5NjAsIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsXG4gICAgICAweGUzYmM0NTk1LCAweGE2N2JjODgzLCAweGIxN2YzN2QxLCAweDAxOGNmZjI4LCAweGMzMzJkZGVmLCAweGJlNmM1YWE1LFxuICAgICAgMHg2NTU4MjE4NSwgMHg2OGFiOTgwMiwgMHhlZWNlYTUwZiwgMHhkYjJmOTUzYiwgMHgyYWVmN2RhZCwgMHg1YjZlMmY4NCxcbiAgICAgIDB4MTUyMWI2MjgsIDB4MjkwNzYxNzAsIDB4ZWNkZDQ3NzUsIDB4NjE5ZjE1MTAsIDB4MTNjY2E4MzAsIDB4ZWI2MWJkOTYsXG4gICAgICAweDAzMzRmZTFlLCAweGFhMDM2M2NmLCAweGI1NzM1YzkwLCAweDRjNzBhMjM5LCAweGQ1OWU5ZTBiLCAweGNiYWFkZTE0LFxuICAgICAgMHhlZWNjODZiYywgMHg2MDYyMmNhNywgMHg5Y2FiNWNhYiwgMHhiMmYzODQ2ZSwgMHg2NDhiMWVhZiwgMHgxOWJkZjBjYSxcbiAgICAgIDB4YTAyMzY5YjksIDB4NjU1YWJiNTAsIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsXG4gICAgICAweDliNTQwYjE5LCAweDg3NWZhMDk5LCAweDk1Zjc5OTdlLCAweDYyM2Q3ZGE4LCAweGY4Mzc4ODlhLCAweDk3ZTMyZDc3LFxuICAgICAgMHgxMWVkOTM1ZiwgMHgxNjY4MTI4MSwgMHgwZTM1ODgyOSwgMHhjN2U2MWZkNiwgMHg5NmRlZGZhMSwgMHg3ODU4YmE5OSxcbiAgICAgIDB4NTdmNTg0YTUsIDB4MWIyMjcyNjMsIDB4OWI4M2MzZmYsIDB4MWFjMjQ2OTYsIDB4Y2RiMzBhZWIsIDB4NTMyZTMwNTQsXG4gICAgICAweDhmZDk0OGU0LCAweDZkYmMzMTI4LCAweDU4ZWJmMmVmLCAweDM0YzZmZmVhLCAweGZlMjhlZDYxLCAweGVlN2MzYzczLFxuICAgICAgMHg1ZDRhMTRkOSwgMHhlODY0YjdlMywgMHg0MjEwNWQxNCwgMHgyMDNlMTNlMCwgMHg0NWVlZTJiNiwgMHhhM2FhYWJlYSxcbiAgICAgIDB4ZGI2YzRmMTUsIDB4ZmFjYjRmZDAsIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsXG4gICAgICAweGQ4MWU3OTllLCAweDg2ODU0ZGM3LCAweGU0NGI0NzZhLCAweDNkODE2MjUwLCAweGNmNjJhMWYyLCAweDViOGQyNjQ2LFxuICAgICAgMHhmYzg4ODNhMCwgMHhjMWM3YjZhMywgMHg3ZjE1MjRjMywgMHg2OWNiNzQ5MiwgMHg0Nzg0OGEwYiwgMHg1NjkyYjI4NSxcbiAgICAgIDB4MDk1YmJmMDAsIDB4YWQxOTQ4OWQsIDB4MTQ2MmIxNzQsIDB4MjM4MjBlMDAsIDB4NTg0MjhkMmEsIDB4MGM1NWY1ZWEsXG4gICAgICAweDFkYWRmNDNlLCAweDIzM2Y3MDYxLCAweDMzNzJmMDkyLCAweDhkOTM3ZTQxLCAweGQ2NWZlY2YxLCAweDZjMjIzYmRiLFxuICAgICAgMHg3Y2RlMzc1OSwgMHhjYmVlNzQ2MCwgMHg0MDg1ZjJhNywgMHhjZTc3MzI2ZSwgMHhhNjA3ODA4NCwgMHgxOWY4NTA5ZSxcbiAgICAgIDB4ZThlZmQ4NTUsIDB4NjFkOTk3MzUsIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsXG4gICAgICAweDllNDQ3YTJlLCAweGMzNDUzNDg0LCAweGZkZDU2NzA1LCAweDBlMWU5ZWM5LCAweGRiNzNkYmQzLCAweDEwNTU4OGNkLFxuICAgICAgMHg2NzVmZGE3OSwgMHhlMzY3NDM0MCwgMHhjNWM0MzQ2NSwgMHg3MTNlMzhkOCwgMHgzZDI4Zjg5ZSwgMHhmMTZkZmYyMCxcbiAgICAgIDB4MTUzZTIxZTcsIDB4OGZiMDNkNGEsIDB4ZTZlMzlmMmIsIDB4ZGI4M2FkZjdcbiAgXSxcbiAgW1xuICAgICAgMHhlOTNkNWE2OCwgMHg5NDgxNDBmNywgMHhmNjRjMjYxYywgMHg5NDY5MjkzNCwgMHg0MTE1MjBmNywgMHg3NjAyZDRmNyxcbiAgICAgIDB4YmNmNDZiMmUsIDB4ZDRhMjAwNjgsIDB4ZDQwODI0NzEsIDB4MzMyMGY0NmEsIDB4NDNiN2Q0YjcsIDB4NTAwMDYxYWYsXG4gICAgICAweDFlMzlmNjJlLCAweDk3MjQ0NTQ2LCAweDE0MjE0Zjc0LCAweGJmOGI4ODQwLCAweDRkOTVmYzFkLCAweDk2YjU5MWFmLFxuICAgICAgMHg3MGY0ZGRkMywgMHg2NmEwMmY0NSwgMHhiZmJjMDllYywgMHgwM2JkOTc4NSwgMHg3ZmFjNmRkMCwgMHgzMWNiODUwNCxcbiAgICAgIDB4OTZlYjI3YjMsIDB4NTVmZDM5NDEsIDB4ZGEyNTQ3ZTYsIDB4YWJjYTBhOWEsIDB4Mjg1MDc4MjUsIDB4NTMwNDI5ZjQsXG4gICAgICAweDBhMmM4NmRhLCAweGU5YjY2ZGZiLCAweDY4ZGMxNDYyLCAweGQ3NDg2OTAwLCAweDY4MGVjMGE0LCAweDI3YTE4ZGVlLFxuICAgICAgMHg0ZjNmZmVhMiwgMHhlODg3YWQ4YywgMHhiNThjZTAwNiwgMHg3YWY0ZDZiNiwgMHhhYWNlMWU3YywgMHhkMzM3NWZlYyxcbiAgICAgIDB4Y2U3OGEzOTksIDB4NDA2YjJhNDIsIDB4MjBmZTllMzUsIDB4ZDlmMzg1YjksIDB4ZWUzOWQ3YWIsIDB4M2IxMjRlOGIsXG4gICAgICAweDFkYzlmYWY3LCAweDRiNmQxODU2LCAweDI2YTM2NjMxLCAweGVhZTM5N2IyLCAweDNhNmVmYTc0LCAweGRkNWI0MzMyLFxuICAgICAgMHg2ODQxZTdmNywgMHhjYTc4MjBmYiwgMHhmYjBhZjU0ZSwgMHhkOGZlYjM5NywgMHg0NTQwNTZhYywgMHhiYTQ4OTUyNyxcbiAgICAgIDB4NTU1MzNhM2EsIDB4MjA4MzhkODcsIDB4ZmU2YmE5YjcsIDB4ZDA5Njk1NGIsIDB4NTVhODY3YmMsIDB4YTExNTlhNTgsXG4gICAgICAweGNjYTkyOTYzLCAweDk5ZTFkYjMzLCAweGE2MmE0YTU2LCAweDNmMzEyNWY5LCAweDVlZjQ3ZTFjLCAweDkwMjkzMTdjLFxuICAgICAgMHhmZGY4ZTgwMiwgMHgwNDI3MmY3MCwgMHg4MGJiMTU1YywgMHgwNTI4MmNlMywgMHg5NWMxMTU0OCwgMHhlNGM2NmQyMixcbiAgICAgIDB4NDhjMTEzM2YsIDB4YzcwZjg2ZGMsIDB4MDdmOWM5ZWUsIDB4NDEwNDFmMGYsIDB4NDA0Nzc5YTQsIDB4NWQ4ODZlMTcsXG4gICAgICAweDMyNWY1MWViLCAweGQ1OWJjMGQxLCAweGYyYmNjMThmLCAweDQxMTEzNTY0LCAweDI1N2I3ODM0LCAweDYwMmE5YzYwLFxuICAgICAgMHhkZmY4ZThhMywgMHgxZjYzNmMxYiwgMHgwZTEyYjRjMiwgMHgwMmUxMzI5ZSwgMHhhZjY2NGZkMSwgMHhjYWQxODExNSxcbiAgICAgIDB4NmIyMzk1ZTAsIDB4MzMzZTkyZTEsIDB4M2IyNDBiNjIsIDB4ZWViZWI5MjIsIDB4ODViMmEyMGUsIDB4ZTZiYTBkOTksXG4gICAgICAweGRlNzIwYzhjLCAweDJkYTJmNzI4LCAweGQwMTI3ODQ1LCAweDk1Yjc5NGZkLCAweDY0N2QwODYyLCAweGU3Y2NmNWYwLFxuICAgICAgMHg1NDQ5YTM2ZiwgMHg4NzdkNDhmYSwgMHhjMzlkZmQyNywgMHhmMzNlOGQxZSwgMHgwYTQ3NjM0MSwgMHg5OTJlZmY3NCxcbiAgICAgIDB4M2E2ZjZlYWIsIDB4ZjRmOGZkMzcsIDB4YTgxMmRjNjAsIDB4YTFlYmRkZjgsIDB4OTkxYmUxNGMsIDB4ZGI2ZTZiMGQsXG4gICAgICAweGM2N2I1NTEwLCAweDZkNjcyYzM3LCAweDI3NjVkNDNiLCAweGRjZDBlODA0LCAweGYxMjkwZGM3LCAweGNjMDBmZmEzLFxuICAgICAgMHhiNTM5MGY5MiwgMHg2OTBmZWQwYiwgMHg2NjdiOWZmYiwgMHhjZWRiN2Q5YywgMHhhMDkxY2YwYiwgMHhkOTE1NWVhMyxcbiAgICAgIDB4YmIxMzJmODgsIDB4NTE1YmFkMjQsIDB4N2I5NDc5YmYsIDB4NzYzYmQ2ZWIsIDB4MzczOTJlYjMsIDB4Y2MxMTU5NzksXG4gICAgICAweDgwMjZlMjk3LCAweGY0MmUzMTJkLCAweDY4NDJhZGE3LCAweGM2NmEyYjNiLCAweDEyNzU0Y2NjLCAweDc4MmVmMTFjLFxuICAgICAgMHg2YTEyNDIzNywgMHhiNzkyNTFlNywgMHgwNmExYmJlNiwgMHg0YmZiNjM1MCwgMHgxYTZiMTAxOCwgMHgxMWNhZWRmYSxcbiAgICAgIDB4M2QyNWJkZDgsIDB4ZTJlMWMzYzksIDB4NDQ0MjE2NTksIDB4MGExMjEzODYsIDB4ZDkwY2VjNmUsIDB4ZDVhYmVhMmEsXG4gICAgICAweDY0YWY2NzRlLCAweGRhODZhODVmLCAweGJlYmZlOTg4LCAweDY0ZTRjM2ZlLCAweDlkYmM4MDU3LCAweGYwZjdjMDg2LFxuICAgICAgMHg2MDc4N2JmOCwgMHg2MDAzNjA0ZCwgMHhkMWZkODM0NiwgMHhmNjM4MWZiMCwgMHg3NzQ1YWUwNCwgMHhkNzM2ZmNjYyxcbiAgICAgIDB4ODM0MjZiMzMsIDB4ZjAxZWFiNzEsIDB4YjA4MDQxODcsIDB4M2MwMDVlNWYsIDB4NzdhMDU3YmUsIDB4YmRlOGFlMjQsXG4gICAgICAweDU1NDY0Mjk5LCAweGJmNTgyZTYxLCAweDRlNThmNDhmLCAweGYyZGRmZGEyLCAweGY0NzRlZjM4LCAweDg3ODliZGMyLFxuICAgICAgMHg1MzY2ZjljMywgMHhjOGIzOGU3NCwgMHhiNDc1ZjI1NSwgMHg0NmZjZDliOSwgMHg3YWViMjY2MSwgMHg4YjFkZGY4NCxcbiAgICAgIDB4ODQ2YTBlNzksIDB4OTE1Zjk1ZTIsIDB4NDY2ZTU5OGUsIDB4MjBiNDU3NzAsIDB4OGNkNTU1OTEsIDB4YzkwMmRlNGMsXG4gICAgICAweGI5MGJhY2UxLCAweGJiODIwNWQwLCAweDExYTg2MjQ4LCAweDc1NzRhOTllLCAweGI3N2YxOWI2LCAweGUwYTlkYzA5LFxuICAgICAgMHg2NjJkMDlhMSwgMHhjNDMyNDYzMywgMHhlODVhMWYwMiwgMHgwOWYwYmU4YywgMHg0YTk5YTAyNSwgMHgxZDZlZmUxMCxcbiAgICAgIDB4MWFiOTNkMWQsIDB4MGJhNWE0ZGYsIDB4YTE4NmYyMGYsIDB4Mjg2OGYxNjksIDB4ZGNiN2RhODMsIDB4NTczOTA2ZmUsXG4gICAgICAweGExZTJjZTliLCAweDRmY2Q3ZjUyLCAweDUwMTE1ZTAxLCAweGE3MDY4M2ZhLCAweGEwMDJiNWM0LCAweDBkZTZkMDI3LFxuICAgICAgMHg5YWY4OGMyNywgMHg3NzNmODY0MSwgMHhjMzYwNGMwNiwgMHg2MWE4MDZiNSwgMHhmMDE3N2EyOCwgMHhjMGY1ODZlMCxcbiAgICAgIDB4MDA2MDU4YWEsIDB4MzBkYzdkNjIsIDB4MTFlNjllZDcsIDB4MjMzOGVhNjMsIDB4NTNjMmRkOTQsIDB4YzJjMjE2MzQsXG4gICAgICAweGJiY2JlZTU2LCAweDkwYmNiNmRlLCAweGViZmM3ZGExLCAweGNlNTkxZDc2LCAweDZmMDVlNDA5LCAweDRiN2MwMTg4LFxuICAgICAgMHgzOTcyMGEzZCwgMHg3YzkyN2MyNCwgMHg4NmUzNzI1ZiwgMHg3MjRkOWRiOSwgMHgxYWMxNWJiNCwgMHhkMzllYjhmYyxcbiAgICAgIDB4ZWQ1NDU1NzgsIDB4MDhmY2E1YjUsIDB4ZDgzZDdjZDMsIDB4NGRhZDBmYzQsIDB4MWU1MGVmNWUsIDB4YjE2MWU2ZjgsXG4gICAgICAweGEyODUxNGQ5LCAweDZjNTExMzNjLCAweDZmZDVjN2U3LCAweDU2ZTE0ZWM0LCAweDM2MmFiZmNlLCAweGRkYzZjODM3LFxuICAgICAgMHhkNzlhMzIzNCwgMHg5MjYzODIxMiwgMHg2NzBlZmE4ZSwgMHg0MDYwMDBlMFxuICBdLFxuICBbXG4gICAgICAweDNhMzljZTM3LCAweGQzZmFmNWNmLCAweGFiYzI3NzM3LCAweDVhYzUyZDFiLCAweDVjYjA2NzllLCAweDRmYTMzNzQyLFxuICAgICAgMHhkMzgyMjc0MCwgMHg5OWJjOWJiZSwgMHhkNTExOGU5ZCwgMHhiZjBmNzMxNSwgMHhkNjJkMWM3ZSwgMHhjNzAwYzQ3YixcbiAgICAgIDB4Yjc4YzFiNmIsIDB4MjFhMTkwNDUsIDB4YjI2ZWIxYmUsIDB4NmEzNjZlYjQsIDB4NTc0OGFiMmYsIDB4YmM5NDZlNzksXG4gICAgICAweGM2YTM3NmQyLCAweDY1NDljMmM4LCAweDUzMGZmOGVlLCAweDQ2OGRkZTdkLCAweGQ1NzMwYTFkLCAweDRjZDA0ZGM2LFxuICAgICAgMHgyOTM5YmJkYiwgMHhhOWJhNDY1MCwgMHhhYzk1MjZlOCwgMHhiZTVlZTMwNCwgMHhhMWZhZDVmMCwgMHg2YTJkNTE5YSxcbiAgICAgIDB4NjNlZjhjZTIsIDB4OWE4NmVlMjIsIDB4YzA4OWMyYjgsIDB4NDMyNDJlZjYsIDB4YTUxZTAzYWEsIDB4OWNmMmQwYTQsXG4gICAgICAweDgzYzA2MWJhLCAweDliZTk2YTRkLCAweDhmZTUxNTUwLCAweGJhNjQ1YmQ2LCAweDI4MjZhMmY5LCAweGE3M2EzYWUxLFxuICAgICAgMHg0YmE5OTU4NiwgMHhlZjU1NjJlOSwgMHhjNzJmZWZkMywgMHhmNzUyZjdkYSwgMHgzZjA0NmY2OSwgMHg3N2ZhMGE1OSxcbiAgICAgIDB4ODBlNGE5MTUsIDB4ODdiMDg2MDEsIDB4OWIwOWU2YWQsIDB4M2IzZWU1OTMsIDB4ZTk5MGZkNWEsIDB4OWUzNGQ3OTcsXG4gICAgICAweDJjZjBiN2Q5LCAweDAyMmI4YjUxLCAweDk2ZDVhYzNhLCAweDAxN2RhNjdkLCAweGQxY2YzZWQ2LCAweDdjN2QyZDI4LFxuICAgICAgMHgxZjlmMjVjZiwgMHhhZGYyYjg5YiwgMHg1YWQ2YjQ3MiwgMHg1YTg4ZjU0YywgMHhlMDI5YWM3MSwgMHhlMDE5YTVlNixcbiAgICAgIDB4NDdiMGFjZmQsIDB4ZWQ5M2ZhOWIsIDB4ZThkM2M0OGQsIDB4MjgzYjU3Y2MsIDB4ZjhkNTY2MjksIDB4NzkxMzJlMjgsXG4gICAgICAweDc4NWYwMTkxLCAweGVkNzU2MDU1LCAweGY3OTYwZTQ0LCAweGUzZDM1ZThjLCAweDE1MDU2ZGQ0LCAweDg4ZjQ2ZGJhLFxuICAgICAgMHgwM2ExNjEyNSwgMHgwNTY0ZjBiZCwgMHhjM2ViOWUxNSwgMHgzYzkwNTdhMiwgMHg5NzI3MWFlYywgMHhhOTNhMDcyYSxcbiAgICAgIDB4MWIzZjZkOWIsIDB4MWU2MzIxZjUsIDB4ZjU5YzY2ZmIsIDB4MjZkY2YzMTksIDB4NzUzM2Q5MjgsIDB4YjE1NWZkZjUsXG4gICAgICAweDAzNTYzNDgyLCAweDhhYmEzY2JiLCAweDI4NTE3NzExLCAweGMyMGFkOWY4LCAweGFiY2M1MTY3LCAweGNjYWQ5MjVmLFxuICAgICAgMHg0ZGU4MTc1MSwgMHgzODMwZGM4ZSwgMHgzNzlkNTg2MiwgMHg5MzIwZjk5MSwgMHhlYTdhOTBjMiwgMHhmYjNlN2JjZSxcbiAgICAgIDB4NTEyMWNlNjQsIDB4Nzc0ZmJlMzIsIDB4YThiNmUzN2UsIDB4YzMyOTNkNDYsIDB4NDhkZTUzNjksIDB4NjQxM2U2ODAsXG4gICAgICAweGEyYWUwODEwLCAweGRkNmRiMjI0LCAweDY5ODUyZGZkLCAweDA5MDcyMTY2LCAweGIzOWE0NjBhLCAweDY0NDVjMGRkLFxuICAgICAgMHg1ODZjZGVjZiwgMHgxYzIwYzhhZSwgMHg1YmJlZjdkZCwgMHgxYjU4OGQ0MCwgMHhjY2QyMDE3ZiwgMHg2YmI0ZTNiYixcbiAgICAgIDB4ZGRhMjZhN2UsIDB4M2E1OWZmNDUsIDB4M2UzNTBhNDQsIDB4YmNiNGNkZDUsIDB4NzJlYWNlYTgsIDB4ZmE2NDg0YmIsXG4gICAgICAweDhkNjYxMmFlLCAweGJmM2M2ZjQ3LCAweGQyOWJlNDYzLCAweDU0MmY1ZDllLCAweGFlYzI3NzFiLCAweGY2NGU2MzcwLFxuICAgICAgMHg3NDBlMGQ4ZCwgMHhlNzViMTM1NywgMHhmODcyMTY3MSwgMHhhZjUzN2Q1ZCwgMHg0MDQwY2IwOCwgMHg0ZWI0ZTJjYyxcbiAgICAgIDB4MzRkMjQ2NmEsIDB4MDExNWFmODQsIDB4ZTFiMDA0MjgsIDB4OTU5ODNhMWQsIDB4MDZiODlmYjQsIDB4Y2U2ZWEwNDgsXG4gICAgICAweDZmM2YzYjgyLCAweDM1MjBhYjgyLCAweDAxMWExZDRiLCAweDI3NzIyN2Y4LCAweDYxMTU2MGIxLCAweGU3OTMzZmRjLFxuICAgICAgMHhiYjNhNzkyYiwgMHgzNDQ1MjViZCwgMHhhMDg4MzllMSwgMHg1MWNlNzk0YiwgMHgyZjMyYzliNywgMHhhMDFmYmFjOSxcbiAgICAgIDB4ZTAxY2M4N2UsIDB4YmNjN2QxZjYsIDB4Y2YwMTExYzMsIDB4YTFlOGFhYzcsIDB4MWE5MDg3NDksIDB4ZDQ0ZmJkOWEsXG4gICAgICAweGQwZGFkZWNiLCAweGQ1MGFkYTM4LCAweDAzMzljMzJhLCAweGM2OTEzNjY3LCAweDhkZjkzMTdjLCAweGUwYjEyYjRmLFxuICAgICAgMHhmNzllNTliNywgMHg0M2Y1YmIzYSwgMHhmMmQ1MTlmZiwgMHgyN2Q5NDU5YywgMHhiZjk3MjIyYywgMHgxNWU2ZmMyYSxcbiAgICAgIDB4MGY5MWZjNzEsIDB4OWI5NDE1MjUsIDB4ZmFlNTkzNjEsIDB4Y2ViNjljZWIsIDB4YzJhODY0NTksIDB4MTJiYWE4ZDEsXG4gICAgICAweGI2YzEwNzVlLCAweGUzMDU2YTBjLCAweDEwZDI1MDY1LCAweGNiMDNhNDQyLCAweGUwZWM2ZTBlLCAweDE2OThkYjNiLFxuICAgICAgMHg0Yzk4YTBiZSwgMHgzMjc4ZTk2NCwgMHg5ZjFmOTUzMiwgMHhlMGQzOTJkZiwgMHhkM2EwMzQyYiwgMHg4OTcxZjIxZSxcbiAgICAgIDB4MWIwYTc0NDEsIDB4NGJhMzM0OGMsIDB4YzViZTcxMjAsIDB4YzM3NjMyZDgsIDB4ZGYzNTlmOGQsIDB4OWI5OTJmMmUsXG4gICAgICAweGU2MGI2ZjQ3LCAweDBmZTNmMTFkLCAweGU1NGNkYTU0LCAweDFlZGFkODkxLCAweGNlNjI3OWNmLCAweGNkM2U3ZTZmLFxuICAgICAgMHgxNjE4YjE2NiwgMHhmZDJjMWQwNSwgMHg4NDhmZDJjNSwgMHhmNmZiMjI5OSwgMHhmNTIzZjM1NywgMHhhNjMyNzYyMyxcbiAgICAgIDB4OTNhODM1MzEsIDB4NTZjY2NkMDIsIDB4YWNmMDgxNjIsIDB4NWE3NWViYjUsIDB4NmUxNjM2OTcsIDB4ODhkMjczY2MsXG4gICAgICAweGRlOTY2MjkyLCAweDgxYjk0OWQwLCAweDRjNTA5MDFiLCAweDcxYzY1NjE0LCAweGU2YzZjN2JkLCAweDMyN2ExNDBhLFxuICAgICAgMHg0NWUxZDAwNiwgMHhjM2YyN2I5YSwgMHhjOWFhNTNmZCwgMHg2MmE4MGYwMCwgMHhiYjI1YmZlMiwgMHgzNWJkZDJmNixcbiAgICAgIDB4NzExMjY5MDUsIDB4YjIwNDAyMjIsIDB4YjZjYmNmN2MsIDB4Y2Q3NjljMmIsIDB4NTMxMTNlYzAsIDB4MTY0MGUzZDMsXG4gICAgICAweDM4YWJiZDYwLCAweDI1NDdhZGYwLCAweGJhMzgyMDljLCAweGY3NDZjZTc2LCAweDc3YWZhMWM1LCAweDIwNzU2MDYwLFxuICAgICAgMHg4NWNiZmU0ZSwgMHg4YWU4OGRkOCwgMHg3YWFhZjliMCwgMHg0Y2Y5YWE3ZSwgMHgxOTQ4YzI1YywgMHgwMmZiOGE4YyxcbiAgICAgIDB4MDFjMzZhZTQsIDB4ZDZlYmUxZjksIDB4OTBkNGY4NjksIDB4YTY1Y2RlYTAsIDB4M2YwOTI1MmQsIDB4YzIwOGU2OWYsXG4gICAgICAweGI3NGU2MTMyLCAweGNlNzdlMjViLCAweDU3OGZkZmUzLCAweDNhYzM3MmU2XG4gIF1cbl07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIGRlZmF1bHQgUEFSUkFZXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5QQVJSQVkgPSBbXG4gICAgMHgyNDNmNmE4OCwgMHg4NWEzMDhkMywgMHgxMzE5OGEyZSwgMHgwMzcwNzM0NCwgMHhhNDA5MzgyMiwgMHgyOTlmMzFkMCxcbiAgICAweDA4MmVmYTk4LCAweGVjNGU2Yzg5LCAweDQ1MjgyMWU2LCAweDM4ZDAxMzc3LCAweGJlNTQ2NmNmLCAweDM0ZTkwYzZjLFxuICAgIDB4YzBhYzI5YjcsIDB4Yzk3YzUwZGQsIDB4M2Y4NGQ1YjUsIDB4YjU0NzA5MTcsIDB4OTIxNmQ1ZDksIDB4ODk3OWZiMWJcbl07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIG51bWJlciBvZiByb3VuZHMgdGhlIGNpcGhlciB3aWxsIGdvXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5OTiA9IDE2O1xuXG4vLypcbi8vKiBUaGlzIGZ1bmN0aW9uIGlzIG5lZWRlZCB0byBnZXQgcmlkIG9mIHByb2JsZW1zXG4vLyogd2l0aCB0aGUgaGlnaC1iaXQgZ2V0dGluZyBzZXQuICBJZiB3ZSBkb24ndCBkb1xuLy8qIHRoaXMsIHRoZW4gc29tZXRpbWVzICggYWEgJiAweDAwRkZGRkZGRkYgKSBpcyBub3Rcbi8vKiBlcXVhbCB0byAoIGJiICYgMHgwMEZGRkZGRkZGICkgZXZlbiB3aGVuIHRoZXlcbi8vKiBhZ3JlZSBiaXQtZm9yLWJpdCBmb3IgdGhlIGZpcnN0IDMyIGJpdHMuXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fY2xlYW4gPSBmdW5jdGlvbih4eCkge1xuICBpZiAoeHggPCAwKSB7XG4gICAgdmFyIHl5ID0geHggJiAweDdGRkZGRkZGO1xuICAgIHh4ID0geXkgKyAweDgwMDAwMDAwO1xuICB9XG4gIHJldHVybiB4eDtcbn07XG5cbi8vKlxuLy8qIFRoaXMgaXMgdGhlIG1peGluZyBmdW5jdGlvbiB0aGF0IHVzZXMgdGhlIHNib3hlc1xuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX0YgPSBmdW5jdGlvbih4eCkge1xuICB2YXIgYWE7XG4gIHZhciBiYjtcbiAgdmFyIGNjO1xuICB2YXIgZGQ7XG4gIHZhciB5eTtcblxuICBkZCA9IHh4ICYgMHgwMEZGO1xuICB4eCA+Pj49IDg7XG4gIGNjID0geHggJiAweDAwRkY7XG4gIHh4ID4+Pj0gODtcbiAgYmIgPSB4eCAmIDB4MDBGRjtcbiAgeHggPj4+PSA4O1xuICBhYSA9IHh4ICYgMHgwMEZGO1xuXG4gIHl5ID0gdGhpcy5zYm94ZXNbMF1bYWFdICsgdGhpcy5zYm94ZXNbMV1bYmJdO1xuICB5eSA9IHl5IF4gdGhpcy5zYm94ZXNbMl1bY2NdO1xuICB5eSA9IHl5ICsgdGhpcy5zYm94ZXNbM11bZGRdO1xuXG4gIHJldHVybiB5eTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGFuIGFycmF5IHdpdGggdHdvIHZhbHVlcywgbGVmdCBhbmQgcmlnaHRcbi8vKiBhbmQgZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmFscykge1xuICB2YXIgZGF0YUwgPSB2YWxzWzBdO1xuICB2YXIgZGF0YVIgPSB2YWxzWzFdO1xuXG4gIHZhciBpaTtcblxuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OOyArK2lpKSB7XG4gICAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5W2lpXTtcbiAgICBkYXRhUiA9IHRoaXMuX0YoZGF0YUwpIF4gZGF0YVI7XG5cbiAgICB2YXIgdG1wID0gZGF0YUw7XG4gICAgZGF0YUwgPSBkYXRhUjtcbiAgICBkYXRhUiA9IHRtcDtcbiAgfVxuXG4gIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVt0aGlzLk5OICsgMF07XG4gIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVt0aGlzLk5OICsgMV07XG5cbiAgdmFsc1swXSA9IHRoaXMuX2NsZWFuKGRhdGFSKTtcbiAgdmFsc1sxXSA9IHRoaXMuX2NsZWFuKGRhdGFMKTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGEgdmVjdG9yIG9mIG51bWJlcnMgYW5kIHR1cm5zIHRoZW1cbi8vKiBpbnRvIGxvbmcgd29yZHMgc28gdGhhdCB0aGV5IGNhbiBiZSBwcm9jZXNzZWQgYnkgdGhlXG4vLyogcmVhbCBhbGdvcml0aG0uXG4vLypcbi8vKiBNYXliZSBJIHNob3VsZCBtYWtlIHRoZSByZWFsIGFsZ29yaXRobSBhYm92ZSB0YWtlIGEgdmVjdG9yXG4vLyogaW5zdGVhZC4gIFRoYXQgd2lsbCBpbnZvbHZlIG1vcmUgbG9vcGluZywgYnV0IGl0IHdvbid0IHJlcXVpcmVcbi8vKiB0aGUgRigpIG1ldGhvZCB0byBkZWNvbnN0cnVjdCB0aGUgdmVjdG9yLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuZW5jcnlwdF9ibG9jayA9IGZ1bmN0aW9uKHZlY3Rvcikge1xuICB2YXIgaWk7XG4gIHZhciB2YWxzID0gWzAsIDBdO1xuICB2YXIgb2ZmID0gdGhpcy5CTE9DS1NJWkUgLyAyO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRSAvIDI7ICsraWkpIHtcbiAgICB2YWxzWzBdID0gKHZhbHNbMF0gPDwgOCkgfCAodmVjdG9yW2lpICsgMF0gJiAweDAwRkYpO1xuICAgIHZhbHNbMV0gPSAodmFsc1sxXSA8PCA4KSB8ICh2ZWN0b3JbaWkgKyBvZmZdICYgMHgwMEZGKTtcbiAgfVxuXG4gIHRoaXMuX2VuY3J5cHRfYmxvY2sodmFscyk7XG5cbiAgdmFyIHJldCA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRSAvIDI7ICsraWkpIHtcbiAgICByZXRbaWkgKyAwXSA9ICh2YWxzWzBdID4+PiAoMjQgLSA4ICogKGlpKSkgJiAweDAwRkYpO1xuICAgIHJldFtpaSArIG9mZl0gPSAodmFsc1sxXSA+Pj4gKDI0IC0gOCAqIChpaSkpICYgMHgwMEZGKTtcbiAgICAvLyB2YWxzWyAwIF0gPSAoIHZhbHNbIDAgXSA+Pj4gOCApO1xuICAgIC8vIHZhbHNbIDEgXSA9ICggdmFsc1sgMSBdID4+PiA4ICk7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzLCBsZWZ0IGFuZCByaWdodFxuLy8qIGFuZCB1bmRvZXMgTk4gcm91bmRzIG9mIEJsb3dmaXNoIG9uIHRoZW0uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fZGVjcnlwdF9ibG9jayA9IGZ1bmN0aW9uKHZhbHMpIHtcbiAgdmFyIGRhdGFMID0gdmFsc1swXTtcbiAgdmFyIGRhdGFSID0gdmFsc1sxXTtcblxuICB2YXIgaWk7XG5cbiAgZm9yIChpaSA9IHRoaXMuTk4gKyAxOyBpaSA+IDE7IC0taWkpIHtcbiAgICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbaWldO1xuICAgIGRhdGFSID0gdGhpcy5fRihkYXRhTCkgXiBkYXRhUjtcblxuICAgIHZhciB0bXAgPSBkYXRhTDtcbiAgICBkYXRhTCA9IGRhdGFSO1xuICAgIGRhdGFSID0gdG1wO1xuICB9XG5cbiAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WzFdO1xuICBkYXRhUiA9IGRhdGFSIF4gdGhpcy5wYXJyYXlbMF07XG5cbiAgdmFsc1swXSA9IHRoaXMuX2NsZWFuKGRhdGFSKTtcbiAgdmFsc1sxXSA9IHRoaXMuX2NsZWFuKGRhdGFMKTtcbn07XG5cbi8vKlxuLy8qIFRoaXMgbWV0aG9kIHRha2VzIGEga2V5IGFycmF5IGFuZCBpbml0aWFsaXplcyB0aGVcbi8vKiBzYm94ZXMgYW5kIHBhcnJheSBmb3IgdGhpcyBlbmNyeXB0aW9uLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKGtleSkge1xuICB2YXIgaWk7XG4gIHZhciBqaiA9IDA7XG5cbiAgdGhpcy5wYXJyYXkgPSBbXTtcbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5OTiArIDI7ICsraWkpIHtcbiAgICB2YXIgZGF0YSA9IDB4MDAwMDAwMDA7XG4gICAgdmFyIGtrO1xuICAgIGZvciAoa2sgPSAwOyBrayA8IDQ7ICsra2spIHtcbiAgICAgIGRhdGEgPSAoZGF0YSA8PCA4KSB8IChrZXlbampdICYgMHgwMEZGKTtcbiAgICAgIGlmICgrK2pqID49IGtleS5sZW5ndGgpIHtcbiAgICAgICAgamogPSAwO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnBhcnJheVtpaV0gPSB0aGlzLlBBUlJBWVtpaV0gXiBkYXRhO1xuICB9XG5cbiAgdGhpcy5zYm94ZXMgPSBbXTtcbiAgZm9yIChpaSA9IDA7IGlpIDwgNDsgKytpaSkge1xuICAgIHRoaXMuc2JveGVzW2lpXSA9IFtdO1xuICAgIGZvciAoamogPSAwOyBqaiA8IDI1NjsgKytqaikge1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqXSA9IHRoaXMuU0JPWEVTW2lpXVtqal07XG4gICAgfVxuICB9XG5cbiAgdmFyIHZhbHMgPSBbMHgwMDAwMDAwMCwgMHgwMDAwMDAwMF07XG5cbiAgZm9yIChpaSA9IDA7IGlpIDwgdGhpcy5OTiArIDI7IGlpICs9IDIpIHtcbiAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKHZhbHMpO1xuICAgIHRoaXMucGFycmF5W2lpICsgMF0gPSB2YWxzWzBdO1xuICAgIHRoaXMucGFycmF5W2lpICsgMV0gPSB2YWxzWzFdO1xuICB9XG5cbiAgZm9yIChpaSA9IDA7IGlpIDwgNDsgKytpaSkge1xuICAgIGZvciAoamogPSAwOyBqaiA8IDI1NjsgamogKz0gMikge1xuICAgICAgdGhpcy5fZW5jcnlwdF9ibG9jayh2YWxzKTtcbiAgICAgIHRoaXMuc2JveGVzW2lpXVtqaiArIDBdID0gdmFsc1swXTtcbiAgICAgIHRoaXMuc2JveGVzW2lpXVtqaiArIDFdID0gdmFsc1sxXTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIEJGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBiZiA9IG5ldyBCbG93ZmlzaCgpO1xuICBiZi5pbml0KHV0aWwuc3RyMmJpbihrZXkpKTtcbiAgcmV0dXJuIGJmLmVuY3J5cHRfYmxvY2soYmxvY2spO1xufVxuXG5mdW5jdGlvbiBCRihrZXkpIHtcbiAgdGhpcy5iZiA9IG5ldyBCbG93ZmlzaCgpO1xuICB0aGlzLmJmLmluaXQodXRpbC5zdHIyYmluKGtleSkpO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMuYmYuZW5jcnlwdF9ibG9jayhibG9jayk7XG4gIH1cbn1cblxuXG5tb2R1bGUuZXhwb3J0cyA9IEJGO1xubW9kdWxlLmV4cG9ydHMua2V5U2l6ZSA9IEJGLnByb3RvdHlwZS5rZXlTaXplID0gMTY7XG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBCRi5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4iLCIvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZVxuLy8gbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLlxuXG4vLyBDb3B5cmlnaHQgMjAxMCBwamFjb2JzQHhlZWtyLmNvbSAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cbi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuXG4vLyBmaXhlZC9tb2RpZmllZCBieSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlXG4vLyBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbi8vIGNhc3Q1LmpzIGlzIGEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBDQVNULTEyOCwgYXMgZGVmaW5lZCBpbiBSRkMgMjE0NC5cbi8vIENBU1QtMTI4IGlzIGEgY29tbW9uIE9wZW5QR1AgY2lwaGVyLlxuXG5cbi8vIENBU1Q1IGNvbnN0cnVjdG9yXG5cbi8qKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvY2FzdDUgKi9cblxuXG5cbmZ1bmN0aW9uIG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCkge1xuICB0aGlzLkJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuS2V5U2l6ZSA9IDE2O1xuXG4gIHRoaXMuc2V0S2V5ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5tYXNraW5nID0gbmV3IEFycmF5KDE2KTtcbiAgICB0aGlzLnJvdGF0ZSA9IG5ldyBBcnJheSgxNik7XG5cbiAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICBpZiAoa2V5Lmxlbmd0aCA9PSB0aGlzLktleVNpemUpIHtcbiAgICAgIHRoaXMua2V5U2NoZWR1bGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDQVNULTEyODoga2V5cyBtdXN0IGJlIDE2IGJ5dGVzJyk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIHRoaXMucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHRoaXMubWFza2luZ1tpXSA9IDA7XG4gICAgICB0aGlzLnJvdGF0ZVtpXSA9IDA7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZ2V0QmxvY2tTaXplID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEJsb2NrU2l6ZTtcbiAgfTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihzcmMpIHtcbiAgICB2YXIgZHN0ID0gbmV3IEFycmF5KHNyYy5sZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpICs9IDgpIHtcbiAgICAgIHZhciBsID0gc3JjW2ldIDw8IDI0IHwgc3JjW2kgKyAxXSA8PCAxNiB8IHNyY1tpICsgMl0gPDwgOCB8IHNyY1tpICsgM107XG4gICAgICB2YXIgciA9IHNyY1tpICsgNF0gPDwgMjQgfCBzcmNbaSArIDVdIDw8IDE2IHwgc3JjW2kgKyA2XSA8PCA4IHwgc3JjW2kgKyA3XTtcbiAgICAgIHZhciB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzBdLCB0aGlzLnJvdGF0ZVswXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1syXSwgdGhpcy5yb3RhdGVbMl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzNdLCB0aGlzLnJvdGF0ZVszXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s0XSwgdGhpcy5yb3RhdGVbNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzVdLCB0aGlzLnJvdGF0ZVs1XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s3XSwgdGhpcy5yb3RhdGVbN10pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbOF0sIHRoaXMucm90YXRlWzhdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEwXSwgdGhpcy5yb3RhdGVbMTBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxMV0sIHRoaXMucm90YXRlWzExXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxMl0sIHRoaXMucm90YXRlWzEyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTNdLCB0aGlzLnJvdGF0ZVsxM10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzE0XSwgdGhpcy5yb3RhdGVbMTRdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxNV0sIHRoaXMucm90YXRlWzE1XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgZHN0W2ldID0gKHIgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMV0gPSAociA+Pj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyAyXSA9IChyID4+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgM10gPSByICYgMjU1O1xuICAgICAgZHN0W2kgKyA0XSA9IChsID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDVdID0gKGwgPj4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNl0gPSAobCA+Pj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDddID0gbCAmIDI1NTtcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0O1xuICB9O1xuXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKHNyYykge1xuICAgIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkgKz0gOCkge1xuICAgICAgdmFyIGwgPSBzcmNbaV0gPDwgMjQgfCBzcmNbaSArIDFdIDw8IDE2IHwgc3JjW2kgKyAyXSA8PCA4IHwgc3JjW2kgKyAzXTtcbiAgICAgIHZhciByID0gc3JjW2kgKyA0XSA8PCAyNCB8IHNyY1tpICsgNV0gPDwgMTYgfCBzcmNbaSArIDZdIDw8IDggfCBzcmNbaSArIDddO1xuICAgICAgdmFyIHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTVdLCB0aGlzLnJvdGF0ZVsxNV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzE0XSwgdGhpcy5yb3RhdGVbMTRdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxM10sIHRoaXMucm90YXRlWzEzXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMTJdLCB0aGlzLnJvdGF0ZVsxMl0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTFdLCB0aGlzLnJvdGF0ZVsxMV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEwXSwgdGhpcy5yb3RhdGVbMTBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzhdLCB0aGlzLnJvdGF0ZVs4XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s3XSwgdGhpcy5yb3RhdGVbN10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzZdLCB0aGlzLnJvdGF0ZVs2XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbNV0sIHRoaXMucm90YXRlWzVdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1s0XSwgdGhpcy5yb3RhdGVbNF0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbM10sIHRoaXMucm90YXRlWzNdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1syXSwgdGhpcy5yb3RhdGVbMl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzFdLCB0aGlzLnJvdGF0ZVsxXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMF0sIHRoaXMucm90YXRlWzBdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICBkc3RbaV0gPSAociA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyAxXSA9IChyID4+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDJdID0gKHIgPj4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyAzXSA9IHIgJiAyNTU7XG4gICAgICBkc3RbaSArIDRdID0gKGwgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNV0gPSAobCA+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDZdID0gKGwgPj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDddID0gbCAmIDI1NTtcbiAgICB9XG5cbiAgICByZXR1cm4gZHN0O1xuICB9O1xuICB2YXIgc2NoZWR1bGVBID0gbmV3IEFycmF5KDQpO1xuXG4gIHNjaGVkdWxlQVswXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzBdWzBdID0gbmV3IEFycmF5KDQsIDAsIDB4ZCwgMHhmLCAweGMsIDB4ZSwgMHg4KTtcbiAgc2NoZWR1bGVBWzBdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTtcbiAgc2NoZWR1bGVBWzBdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7XG4gIHNjaGVkdWxlQVswXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpO1xuXG4gIHNjaGVkdWxlQVsxXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVBWzFdWzBdID0gbmV3IEFycmF5KDAsIDYsIDE2ICsgNSwgMTYgKyA3LCAxNiArIDQsIDE2ICsgNiwgMTYgKyAwKTtcbiAgc2NoZWR1bGVBWzFdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7XG4gIHNjaGVkdWxlQVsxXVsyXSA9IG5ldyBBcnJheSgyLCA1LCA3LCA2LCA1LCA0LCAxNiArIDEpO1xuICBzY2hlZHVsZUFbMV1bM10gPSBuZXcgQXJyYXkoMywgNywgMHhhLCA5LCAweGIsIDgsIDE2ICsgMyk7XG5cbiAgc2NoZWR1bGVBWzJdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMl1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCA4KTtcbiAgc2NoZWR1bGVBWzJdWzFdID0gbmV3IEFycmF5KDUsIDIsIDE2ICsgMCwgMTYgKyAyLCAxNiArIDEsIDE2ICsgMywgMHhhKTtcbiAgc2NoZWR1bGVBWzJdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7XG4gIHNjaGVkdWxlQVsyXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpO1xuXG5cbiAgc2NoZWR1bGVBWzNdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbM11bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xuICBzY2hlZHVsZUFbM11bMV0gPSBuZXcgQXJyYXkoMSwgNCwgMCwgMiwgMSwgMywgMTYgKyAyKTtcbiAgc2NoZWR1bGVBWzNdWzJdID0gbmV3IEFycmF5KDIsIDUsIDcsIDYsIDUsIDQsIDE2ICsgMSk7XG4gIHNjaGVkdWxlQVszXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcblxuICB2YXIgc2NoZWR1bGVCID0gbmV3IEFycmF5KDQpO1xuXG4gIHNjaGVkdWxlQlswXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzBdWzBdID0gbmV3IEFycmF5KDE2ICsgOCwgMTYgKyA5LCAxNiArIDcsIDE2ICsgNiwgMTYgKyAyKTtcbiAgc2NoZWR1bGVCWzBdWzFdID0gbmV3IEFycmF5KDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA1LCAxNiArIDQsIDE2ICsgNik7XG4gIHNjaGVkdWxlQlswXVsyXSA9IG5ldyBBcnJheSgxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgMywgMTYgKyAyLCAxNiArIDkpO1xuICBzY2hlZHVsZUJbMF1bM10gPSBuZXcgQXJyYXkoMTYgKyAweGUsIDE2ICsgMHhmLCAxNiArIDEsIDE2ICsgMCwgMTYgKyAweGMpO1xuXG4gIHNjaGVkdWxlQlsxXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzFdWzBdID0gbmV3IEFycmF5KDMsIDIsIDB4YywgMHhkLCA4KTtcbiAgc2NoZWR1bGVCWzFdWzFdID0gbmV3IEFycmF5KDEsIDAsIDB4ZSwgMHhmLCAweGQpO1xuICBzY2hlZHVsZUJbMV1bMl0gPSBuZXcgQXJyYXkoNywgNiwgOCwgOSwgMyk7XG4gIHNjaGVkdWxlQlsxXVszXSA9IG5ldyBBcnJheSg1LCA0LCAweGEsIDB4YiwgNyk7XG5cblxuICBzY2hlZHVsZUJbMl0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQlsyXVswXSA9IG5ldyBBcnJheSgxNiArIDMsIDE2ICsgMiwgMTYgKyAweGMsIDE2ICsgMHhkLCAxNiArIDkpO1xuICBzY2hlZHVsZUJbMl1bMV0gPSBuZXcgQXJyYXkoMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAweGMpO1xuICBzY2hlZHVsZUJbMl1bMl0gPSBuZXcgQXJyYXkoMTYgKyA3LCAxNiArIDYsIDE2ICsgOCwgMTYgKyA5LCAxNiArIDIpO1xuICBzY2hlZHVsZUJbMl1bM10gPSBuZXcgQXJyYXkoMTYgKyA1LCAxNiArIDQsIDE2ICsgMHhhLCAxNiArIDB4YiwgMTYgKyA2KTtcblxuXG4gIHNjaGVkdWxlQlszXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzNdWzBdID0gbmV3IEFycmF5KDgsIDksIDcsIDYsIDMpO1xuICBzY2hlZHVsZUJbM11bMV0gPSBuZXcgQXJyYXkoMHhhLCAweGIsIDUsIDQsIDcpO1xuICBzY2hlZHVsZUJbM11bMl0gPSBuZXcgQXJyYXkoMHhjLCAweGQsIDMsIDIsIDgpO1xuICBzY2hlZHVsZUJbM11bM10gPSBuZXcgQXJyYXkoMHhlLCAweGYsIDEsIDAsIDB4ZCk7XG5cbiAgLy8gY2hhbmdlZCAnaW4nIHRvICdpbm4nIChpbiBqYXZhc2NyaXB0ICdpbicgaXMgYSByZXNlcnZlZCB3b3JkKVxuICB0aGlzLmtleVNjaGVkdWxlID0gZnVuY3Rpb24oaW5uKSB7XG4gICAgdmFyIHQgPSBuZXcgQXJyYXkoOCk7XG4gICAgdmFyIGsgPSBuZXcgQXJyYXkoMzIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgIHZhciBqID0gaSAqIDQ7XG4gICAgICB0W2ldID0gaW5uW2pdIDw8IDI0IHwgaW5uW2ogKyAxXSA8PCAxNiB8IGlubltqICsgMl0gPDwgOCB8IGlubltqICsgM107XG4gICAgfVxuXG4gICAgdmFyIHggPSBbNiwgNywgNCwgNV07XG4gICAgdmFyIGtpID0gMDtcblxuICAgIGZvciAodmFyIGhhbGYgPSAwOyBoYWxmIDwgMjsgaGFsZisrKSB7XG4gICAgICBmb3IgKHZhciByb3VuZCA9IDA7IHJvdW5kIDwgNDsgcm91bmQrKykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKykge1xuICAgICAgICAgIHZhciBhID0gc2NoZWR1bGVBW3JvdW5kXVtqXTtcbiAgICAgICAgICB2YXIgdyA9IHRbYVsxXV07XG5cbiAgICAgICAgICB3IF49IHNCb3hbNF1bKHRbYVsyXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVsyXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNV1bKHRbYVszXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVszXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNl1bKHRbYVs0XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs0XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbN11bKHRbYVs1XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs1XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbeFtqXV1bKHRbYVs2XSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYVs2XSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB0W2FbMF1dID0gdztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNDsgaisrKSB7XG4gICAgICAgICAgdmFyIGIgPSBzY2hlZHVsZUJbcm91bmRdW2pdO1xuICAgICAgICAgIHZhciB3ID0gc0JveFs0XVsodFtiWzBdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzBdICYgMykpKSAmIDB4ZmZdO1xuXG4gICAgICAgICAgdyBePSBzQm94WzVdWyh0W2JbMV0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMV0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzZdWyh0W2JbMl0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMl0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzddWyh0W2JbM10gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbM10gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAgdyBePSBzQm94WzQgKyBqXVsodFtiWzRdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChiWzRdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIGtba2ldID0gdztcbiAgICAgICAgICBraSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICB0aGlzLm1hc2tpbmdbaV0gPSBrW2ldO1xuICAgICAgdGhpcy5yb3RhdGVbaV0gPSBrWzE2ICsgaV0gJiAweDFmO1xuICAgIH1cbiAgfTtcblxuICAvLyBUaGVzZSBhcmUgdGhlIHRocmVlICdmJyBmdW5jdGlvbnMuIFNlZSBSRkMgMjE0NCwgc2VjdGlvbiAyLjIuXG5cbiAgZnVuY3Rpb24gZjEoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSArIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gXiBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSAtIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgKyBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgZnVuY3Rpb24gZjIoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSBeIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gLSBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSArIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgXiBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgZnVuY3Rpb24gZjMoZCwgbSwgcikge1xuICAgIHZhciB0ID0gbSAtIGQ7XG4gICAgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XG4gICAgcmV0dXJuICgoc0JveFswXVtJID4+PiAyNF0gKyBzQm94WzFdWyhJID4+PiAxNikgJiAyNTVdKSBeIHNCb3hbMl1bKEkgPj4+IDgpICYgMjU1XSkgLSBzQm94WzNdW0kgJiAyNTVdO1xuICB9XG5cbiAgdmFyIHNCb3ggPSBuZXcgQXJyYXkoOCk7XG4gIHNCb3hbMF0gPSBuZXcgQXJyYXkoXG4gICAgMHgzMGZiNDBkNCwgMHg5ZmEwZmYwYiwgMHg2YmVjY2QyZiwgMHgzZjI1OGM3YSwgMHgxZTIxM2YyZiwgMHg5YzAwNGRkMywgMHg2MDAzZTU0MCwgMHhjZjlmYzk0OSxcbiAgICAweGJmZDRhZjI3LCAweDg4YmJiZGI1LCAweGUyMDM0MDkwLCAweDk4ZDA5Njc1LCAweDZlNjNhMGUwLCAweDE1YzM2MWQyLCAweGMyZTc2NjFkLCAweDIyZDRmZjhlLFxuICAgIDB4Mjg2ODNiNmYsIDB4YzA3ZmQwNTksIDB4ZmYyMzc5YzgsIDB4Nzc1ZjUwZTIsIDB4NDNjMzQwZDMsIDB4ZGYyZjg2NTYsIDB4ODg3Y2E0MWEsIDB4YTJkMmJkMmQsXG4gICAgMHhhMWM5ZTBkNiwgMHgzNDZjNDgxOSwgMHg2MWI3NmQ4NywgMHgyMjU0MGYyZiwgMHgyYWJlMzJlMSwgMHhhYTU0MTY2YiwgMHgyMjU2OGUzYSwgMHhhMmQzNDFkMCxcbiAgICAweDY2ZGI0MGM4LCAweGE3ODQzOTJmLCAweDAwNGRmZjJmLCAweDJkYjlkMmRlLCAweDk3OTQzZmFjLCAweDRhOTdjMWQ4LCAweDUyNzY0NGI3LCAweGI1ZjQzN2E3LFxuICAgIDB4YjgyY2JhZWYsIDB4ZDc1MWQxNTksIDB4NmZmN2YwZWQsIDB4NWEwOTdhMWYsIDB4ODI3YjY4ZDAsIDB4OTBlY2Y1MmUsIDB4MjJiMGMwNTQsIDB4YmM4ZTU5MzUsXG4gICAgMHg0YjZkMmY3ZiwgMHg1MGJiNjRhMiwgMHhkMjY2NDkxMCwgMHhiZWU1ODEyZCwgMHhiNzMzMjI5MCwgMHhlOTNiMTU5ZiwgMHhiNDhlZTQxMSwgMHg0YmZmMzQ1ZCxcbiAgICAweGZkNDVjMjQwLCAweGFkMzE5NzNmLCAweGM0ZjZkMDJlLCAweDU1ZmM4MTY1LCAweGQ1YjFjYWFkLCAweGExYWMyZGFlLCAweGEyZDRiNzZkLCAweGMxOWIwYzUwLFxuICAgIDB4ODgyMjQwZjIsIDB4MGM2ZTRmMzgsIDB4YTRlNGJmZDcsIDB4NGY1YmEyNzIsIDB4NTY0YzFkMmYsIDB4YzU5YzUzMTksIDB4Yjk0OWUzNTQsIDB4YjA0NjY5ZmUsXG4gICAgMHhiMWI2YWI4YSwgMHhjNzEzNThkZCwgMHg2Mzg1YzU0NSwgMHgxMTBmOTM1ZCwgMHg1NzUzOGFkNSwgMHg2YTM5MDQ5MywgMHhlNjNkMzdlMCwgMHgyYTU0ZjZiMyxcbiAgICAweDNhNzg3ZDVmLCAweDYyNzZhMGI1LCAweDE5YTZmY2RmLCAweDdhNDIyMDZhLCAweDI5ZjlkNGQ1LCAweGY2MWIxODkxLCAweGJiNzIyNzVlLCAweGFhNTA4MTY3LFxuICAgIDB4Mzg5MDEwOTEsIDB4YzZiNTA1ZWIsIDB4ODRjN2NiOGMsIDB4MmFkNzVhMGYsIDB4ODc0YTE0MjcsIDB4YTJkMTkzNmIsIDB4MmFkMjg2YWYsIDB4YWE1NmQyOTEsXG4gICAgMHhkNzg5NDM2MCwgMHg0MjVjNzUwZCwgMHg5M2IzOWUyNiwgMHgxODcxODRjOSwgMHg2YzAwYjMyZCwgMHg3M2UyYmIxNCwgMHhhMGJlYmMzYywgMHg1NDYyMzc3OSxcbiAgICAweDY0NDU5ZWFiLCAweDNmMzI4YjgyLCAweDc3MThjZjgyLCAweDU5YTJjZWE2LCAweDA0ZWUwMDJlLCAweDg5ZmU3OGU2LCAweDNmYWIwOTUwLCAweDMyNWZmNmMyLFxuICAgIDB4ODEzODNmMDUsIDB4Njk2M2M1YzgsIDB4NzZjYjVhZDYsIDB4ZDQ5OTc0YzksIDB4Y2ExODBkY2YsIDB4MzgwNzgyZDUsIDB4YzdmYTVjZjYsIDB4OGFjMzE1MTEsXG4gICAgMHgzNWU3OWUxMywgMHg0N2RhOTFkMCwgMHhmNDBmOTA4NiwgMHhhN2UyNDE5ZSwgMHgzMTM2NjI0MSwgMHgwNTFlZjQ5NSwgMHhhYTU3M2IwNCwgMHg0YTgwNWQ4ZCxcbiAgICAweDU0ODMwMGQwLCAweDAwMzIyYTNjLCAweGJmNjRjZGRmLCAweGJhNTdhNjhlLCAweDc1YzYzNzJiLCAweDUwYWZkMzQxLCAweGE3YzEzMjc1LCAweDkxNWEwYmY1LFxuICAgIDB4NmI1NGJmYWIsIDB4MmIwYjE0MjYsIDB4YWI0Y2M5ZDcsIDB4NDQ5Y2NkODIsIDB4ZjdmYmYyNjUsIDB4YWI4NWM1ZjMsIDB4MWI1NWRiOTQsIDB4YWFkNGUzMjQsXG4gICAgMHhjZmE0YmQzZiwgMHgyZGVhYTNlMiwgMHg5ZTIwNGQwMiwgMHhjOGJkMjVhYywgMHhlYWRmNTViMywgMHhkNWJkOWU5OCwgMHhlMzEyMzFiMiwgMHgyYWQ1YWQ2YyxcbiAgICAweDk1NDMyOWRlLCAweGFkYmU0NTI4LCAweGQ4NzEwZjY5LCAweGFhNTFjOTBmLCAweGFhNzg2YmY2LCAweDIyNTEzZjFlLCAweGFhNTFhNzliLCAweDJhZDM0NGNjLFxuICAgIDB4N2I1YTQxZjAsIDB4ZDM3Y2ZiYWQsIDB4MWIwNjk1MDUsIDB4NDFlY2U0OTEsIDB4YjRjMzMyZTYsIDB4MDMyMjY4ZDQsIDB4Yzk2MDBhY2MsIDB4Y2UzODdlNmQsXG4gICAgMHhiZjZiYjE2YywgMHg2YTcwZmI3OCwgMHgwZDAzZDljOSwgMHhkNGRmMzlkZSwgMHhlMDEwNjNkYSwgMHg0NzM2ZjQ2NCwgMHg1YWQzMjhkOCwgMHhiMzQ3Y2M5NixcbiAgICAweDc1YmIwZmMzLCAweDk4NTExYmZiLCAweDRmZmJjYzM1LCAweGI1OGJjZjZhLCAweGUxMWYwYWJjLCAweGJmYzVmZTRhLCAweGE3MGFlYzEwLCAweGFjMzk1NzBhLFxuICAgIDB4M2YwNDQ0MmYsIDB4NjE4OGIxNTMsIDB4ZTAzOTdhMmUsIDB4NTcyN2NiNzksIDB4OWNlYjQxOGYsIDB4MWNhY2Q2OGQsIDB4MmFkMzdjOTYsIDB4MDE3NWNiOWQsXG4gICAgMHhjNjlkZmYwOSwgMHhjNzViNjVmMCwgMHhkOWRiNDBkOCwgMHhlYzBlNzc3OSwgMHg0NzQ0ZWFkNCwgMHhiMTFjMzI3NCwgMHhkZDI0Y2I5ZSwgMHg3ZTFjNTRiZCxcbiAgICAweGYwMTE0NGY5LCAweGQyMjQwZWIxLCAweDk2NzViM2ZkLCAweGEzYWMzNzU1LCAweGQ0N2MyN2FmLCAweDUxYzg1ZjRkLCAweDU2OTA3NTk2LCAweGE1YmIxNWU2LFxuICAgIDB4NTgwMzA0ZjAsIDB4Y2EwNDJjZjEsIDB4MDExYTM3ZWEsIDB4OGRiZmFhZGIsIDB4MzViYTNlNGEsIDB4MzUyNmZmYTAsIDB4YzM3YjRkMDksIDB4YmMzMDZlZDksXG4gICAgMHg5OGE1MjY2NiwgMHg1NjQ4ZjcyNSwgMHhmZjVlNTY5ZCwgMHgwY2VkNjNkMCwgMHg3YzYzYjJjZiwgMHg3MDBiNDVlMSwgMHhkNWVhNTBmMSwgMHg4NWE5Mjg3MixcbiAgICAweGFmMWZiZGE3LCAweGQ0MjM0ODcwLCAweGE3ODcwYmYzLCAweDJkM2I0ZDc5LCAweDQyZTA0MTk4LCAweDBjZDBlZGU3LCAweDI2NDcwZGI4LCAweGY4ODE4MTRjLFxuICAgIDB4NDc0ZDZhZDcsIDB4N2MwYzVlNWMsIDB4ZDEyMzE5NTksIDB4MzgxYjcyOTgsIDB4ZjVkMmY0ZGIsIDB4YWI4Mzg2NTMsIDB4NmUyZjFlMjMsIDB4ODM3MTljOWUsXG4gICAgMHhiZDkxZTA0NiwgMHg5YTU2NDU2ZSwgMHhkYzM5MjAwYywgMHgyMGM4YzU3MSwgMHg5NjJiZGExYywgMHhlMWU2OTZmZiwgMHhiMTQxYWIwOCwgMHg3Y2NhODliOSxcbiAgICAweDFhNjllNzgzLCAweDAyY2M0ODQzLCAweGEyZjdjNTc5LCAweDQyOWVmNDdkLCAweDQyN2IxNjljLCAweDVhYzlmMDQ5LCAweGRkOGYwZjAwLCAweDVjODE2NWJmKTtcblxuICBzQm94WzFdID0gbmV3IEFycmF5KFxuICAgIDB4MWYyMDEwOTQsIDB4ZWYwYmE3NWIsIDB4NjllM2NmN2UsIDB4MzkzZjQzODAsIDB4ZmU2MWNmN2EsIDB4ZWVjNTIwN2EsIDB4NTU4ODljOTQsIDB4NzJmYzA2NTEsXG4gICAgMHhhZGE3ZWY3OSwgMHg0ZTFkNzIzNSwgMHhkNTVhNjNjZSwgMHhkZTA0MzZiYSwgMHg5OWM0MzBlZiwgMHg1ZjBjMDc5NCwgMHgxOGRjZGI3ZCwgMHhhMWQ2ZWZmMyxcbiAgICAweGEwYjUyZjdiLCAweDU5ZTgzNjA1LCAweGVlMTViMDk0LCAweGU5ZmZkOTA5LCAweGRjNDQwMDg2LCAweGVmOTQ0NDU5LCAweGJhODNjY2IzLCAweGUwYzNjZGZiLFxuICAgIDB4ZDFkYTQxODEsIDB4M2IwOTJhYjEsIDB4Zjk5N2YxYzEsIDB4YTVlNmNmN2IsIDB4MDE0MjBkZGIsIDB4ZTRlN2VmNWIsIDB4MjVhMWZmNDEsIDB4ZTE4MGY4MDYsXG4gICAgMHgxZmM0MTA4MCwgMHgxNzliZWU3YSwgMHhkMzdhYzZhOSwgMHhmZTU4MzBhNCwgMHg5OGRlOGI3ZiwgMHg3N2U4M2Y0ZSwgMHg3OTkyOTI2OSwgMHgyNGZhOWY3YixcbiAgICAweGUxMTNjODViLCAweGFjYzQwMDgzLCAweGQ3NTAzNTI1LCAweGY3ZWE2MTVmLCAweDYyMTQzMTU0LCAweDBkNTU0YjYzLCAweDVkNjgxMTIxLCAweGM4NjZjMzU5LFxuICAgIDB4M2Q2M2NmNzMsIDB4Y2VlMjM0YzAsIDB4ZDRkODdlODcsIDB4NWM2NzJiMjEsIDB4MDcxZjYxODEsIDB4MzlmNzYyN2YsIDB4MzYxZTMwODQsIDB4ZTRlYjU3M2IsXG4gICAgMHg2MDJmNjRhNCwgMHhkNjNhY2Q5YywgMHgxYmJjNDYzNSwgMHg5ZTgxMDMyZCwgMHgyNzAxZjUwYywgMHg5OTg0N2FiNCwgMHhhMGUzZGY3OSwgMHhiYTZjZjM4YyxcbiAgICAweDEwODQzMDk0LCAweDI1MzdhOTVlLCAweGY0NmY2ZmZlLCAweGExZmYzYjFmLCAweDIwOGNmYjZhLCAweDhmNDU4Yzc0LCAweGQ5ZTBhMjI3LCAweDRlYzczYTM0LFxuICAgIDB4ZmM4ODRmNjksIDB4M2U0ZGU4ZGYsIDB4ZWYwZTAwODgsIDB4MzU1OTY0OGQsIDB4OGE0NTM4OGMsIDB4MWQ4MDQzNjYsIDB4NzIxZDliZmQsIDB4YTU4Njg0YmIsXG4gICAgMHhlODI1NjMzMywgMHg4NDRlODIxMiwgMHgxMjhkODA5OCwgMHhmZWQzM2ZiNCwgMHhjZTI4MGFlMSwgMHgyN2UxOWJhNSwgMHhkNWE2YzI1MiwgMHhlNDk3NTRiZCxcbiAgICAweGM1ZDY1NWRkLCAweGViNjY3MDY0LCAweDc3ODQwYjRkLCAweGExYjZhODAxLCAweDg0ZGIyNmE5LCAweGUwYjU2NzE0LCAweDIxZjA0M2I3LCAweGU1ZDA1ODYwLFxuICAgIDB4NTRmMDMwODQsIDB4MDY2ZmY0NzIsIDB4YTMxYWExNTMsIDB4ZGFkYzQ3NTUsIDB4YjU2MjVkYmYsIDB4Njg1NjFiZTYsIDB4ODNjYTZiOTQsIDB4MmQ2ZWQyM2IsXG4gICAgMHhlY2NmMDFkYiwgMHhhNmQzZDBiYSwgMHhiNjgwM2Q1YywgMHhhZjc3YTcwOSwgMHgzM2I0YTM0YywgMHgzOTdiYzhkNiwgMHg1ZWUyMmI5NSwgMHg1ZjBlNTMwNCxcbiAgICAweDgxZWQ2ZjYxLCAweDIwZTc0MzY0LCAweGI0NWUxMzc4LCAweGRlMTg2MzliLCAweDg4MWNhMTIyLCAweGI5NjcyNmQxLCAweDgwNDlhN2U4LCAweDIyYjdkYTdiLFxuICAgIDB4NWU1NTJkMjUsIDB4NTI3MmQyMzcsIDB4NzlkMjk1MWMsIDB4YzYwZDg5NGMsIDB4NDg4Y2I0MDIsIDB4MWJhNGZlNWIsIDB4YTRiMDlmNmIsIDB4MWNhODE1Y2YsXG4gICAgMHhhMjBjMzAwNSwgMHg4ODcxZGY2MywgMHhiOWRlMmZjYiwgMHgwY2M2YzllOSwgMHgwYmVlZmY1MywgMHhlMzIxNDUxNywgMHhiNDU0MjgzNSwgMHg5ZjYzMjkzYyxcbiAgICAweGVlNDFlNzI5LCAweDZlMWQyZDdjLCAweDUwMDQ1Mjg2LCAweDFlNjY4NWYzLCAweGYzMzQwMWM2LCAweDMwYTIyYzk1LCAweDMxYTcwODUwLCAweDYwOTMwZjEzLFxuICAgIDB4NzNmOTg0MTcsIDB4YTEyNjk4NTksIDB4ZWM2NDVjNDQsIDB4NTJjODc3YTksIDB4Y2RmZjMzYTYsIDB4YTAyYjE3NDEsIDB4N2NiYWQ5YTIsIDB4MjE4MDAzNmYsXG4gICAgMHg1MGQ5OWMwOCwgMHhjYjNmNDg2MSwgMHhjMjZiZDc2NSwgMHg2NGEzZjZhYiwgMHg4MDM0MjY3NiwgMHgyNWE3NWU3YiwgMHhlNGU2ZDFmYywgMHgyMGM3MTBlNixcbiAgICAweGNkZjBiNjgwLCAweDE3ODQ0ZDNiLCAweDMxZWVmODRkLCAweDdlMDgyNGU0LCAweDJjY2I0OWViLCAweDg0NmEzYmFlLCAweDhmZjc3ODg4LCAweGVlNWQ2MGY2LFxuICAgIDB4N2FmNzU2NzMsIDB4MmZkZDVjZGIsIDB4YTExNjMxYzEsIDB4MzBmNjZmNDMsIDB4YjNmYWVjNTQsIDB4MTU3ZmQ3ZmEsIDB4ZWY4NTc5Y2MsIDB4ZDE1MmRlNTgsXG4gICAgMHhkYjJmZmQ1ZSwgMHg4ZjMyY2UxOSwgMHgzMDZhZjk3YSwgMHgwMmYwM2VmOCwgMHg5OTMxOWFkNSwgMHhjMjQyZmEwZiwgMHhhN2UzZWJiMCwgMHhjNjhlNDkwNixcbiAgICAweGI4ZGEyMzBjLCAweDgwODIzMDI4LCAweGRjZGVmM2M4LCAweGQzNWZiMTcxLCAweDA4OGExYmM4LCAweGJlYzBjNTYwLCAweDYxYTNjOWU4LCAweGJjYThmNTRkLFxuICAgIDB4YzcyZmVmZmEsIDB4MjI4MjJlOTksIDB4ODJjNTcwYjQsIDB4ZDhkOTRlODksIDB4OGIxYzM0YmMsIDB4MzAxZTE2ZTYsIDB4MjczYmU5NzksIDB4YjBmZmVhYTYsXG4gICAgMHg2MWQ5YjhjNiwgMHgwMGIyNDg2OSwgMHhiN2ZmY2UzZiwgMHgwOGRjMjgzYiwgMHg0M2RhZjY1YSwgMHhmN2UxOTc5OCwgMHg3NjE5YjcyZiwgMHg4ZjFjOWJhNCxcbiAgICAweGRjODYzN2EwLCAweDE2YTdkM2IxLCAweDlmYzM5M2I3LCAweGE3MTM2ZWViLCAweGM2YmNjNjNlLCAweDFhNTEzNzQyLCAweGVmNjgyOGJjLCAweDUyMDM2NWQ2LFxuICAgIDB4MmQ2YTc3YWIsIDB4MzUyN2VkNGIsIDB4ODIxZmQyMTYsIDB4MDk1YzZlMmUsIDB4ZGI5MmYyZmIsIDB4NWVlYTI5Y2IsIDB4MTQ1ODkyZjUsIDB4OTE1ODRmN2YsXG4gICAgMHg1NDgzNjk3YiwgMHgyNjY3YThjYywgMHg4NTE5NjA0OCwgMHg4YzRiYWNlYSwgMHg4MzM4NjBkNCwgMHgwZDIzZTBmOSwgMHg2YzM4N2U4YSwgMHgwYWU2ZDI0OSxcbiAgICAweGIyODQ2MDBjLCAweGQ4MzU3MzFkLCAweGRjYjFjNjQ3LCAweGFjNGM1NmVhLCAweDNlYmQ4MWIzLCAweDIzMGVhYmIwLCAweDY0MzhiYzg3LCAweGYwYjViMWZhLFxuICAgIDB4OGY1ZWEyYjMsIDB4ZmMxODQ2NDIsIDB4MGEwMzZiN2EsIDB4NGZiMDg5YmQsIDB4NjQ5ZGE1ODksIDB4YTM0NTQxNWUsIDB4NWMwMzgzMjMsIDB4M2U1ZDNiYjksXG4gICAgMHg0M2Q3OTU3MiwgMHg3ZTZkZDA3YywgMHgwNmRmZGYxZSwgMHg2YzZjYzRlZiwgMHg3MTYwYTUzOSwgMHg3M2JmYmU3MCwgMHg4Mzg3NzYwNSwgMHg0NTIzZWNmMSk7XG5cbiAgc0JveFsyXSA9IG5ldyBBcnJheShcbiAgICAweDhkZWZjMjQwLCAweDI1ZmE1ZDlmLCAweGViOTAzZGJmLCAweGU4MTBjOTA3LCAweDQ3NjA3ZmZmLCAweDM2OWZlNDRiLCAweDhjMWZjNjQ0LCAweGFlY2VjYTkwLFxuICAgIDB4YmViMWY5YmYsIDB4ZWVmYmNhZWEsIDB4ZThjZjE5NTAsIDB4NTFkZjA3YWUsIDB4OTIwZTg4MDYsIDB4ZjBhZDA1NDgsIDB4ZTEzYzhkODMsIDB4OTI3MDEwZDUsXG4gICAgMHgxMTEwN2Q5ZiwgMHgwNzY0N2RiOSwgMHhiMmUzZTRkNCwgMHgzZDRmMjg1ZSwgMHhiOWFmYTgyMCwgMHhmYWRlODJlMCwgMHhhMDY3MjY4YiwgMHg4MjcyNzkyZSxcbiAgICAweDU1M2ZiMmMwLCAweDQ4OWFlMjJiLCAweGQ0ZWY5Nzk0LCAweDEyNWUzZmJjLCAweDIxZmZmY2VlLCAweDgyNWIxYmZkLCAweDkyNTVjNWVkLCAweDEyNTdhMjQwLFxuICAgIDB4NGUxYTgzMDIsIDB4YmFlMDdmZmYsIDB4NTI4MjQ2ZTcsIDB4OGU1NzE0MGUsIDB4MzM3M2Y3YmYsIDB4OGM5ZjgxODgsIDB4YTZmYzRlZTgsIDB4Yzk4MmI1YTUsXG4gICAgMHhhOGMwMWRiNywgMHg1NzlmYzI2NCwgMHg2NzA5NGYzMSwgMHhmMmJkM2Y1ZiwgMHg0MGZmZjdjMSwgMHgxZmI3OGRmYywgMHg4ZTZiZDJjMSwgMHg0MzdiZTU5YixcbiAgICAweDk5YjAzZGJmLCAweGI1ZGJjNjRiLCAweDYzOGRjMGU2LCAweDU1ODE5ZDk5LCAweGExOTdjODFjLCAweDRhMDEyZDZlLCAweGM1ODg0YTI4LCAweGNjYzM2ZjcxLFxuICAgIDB4Yjg0M2MyMTMsIDB4NmMwNzQzZjEsIDB4ODMwOTg5M2MsIDB4MGZlZGRkNWYsIDB4MmY3ZmU4NTAsIDB4ZDdjMDdmN2UsIDB4MDI1MDdmYmYsIDB4NWFmYjlhMDQsXG4gICAgMHhhNzQ3ZDJkMCwgMHgxNjUxMTkyZSwgMHhhZjcwYmYzZSwgMHg1OGMzMTM4MCwgMHg1Zjk4MzAyZSwgMHg3MjdjYzNjNCwgMHgwYTBmYjQwMiwgMHgwZjdmZWY4MixcbiAgICAweDhjOTZmZGFkLCAweDVkMmMyYWFlLCAweDhlZTk5YTQ5LCAweDUwZGE4OGI4LCAweDg0MjdmNGEwLCAweDFlYWM1NzkwLCAweDc5NmZiNDQ5LCAweDgyNTJkYzE1LFxuICAgIDB4ZWZiZDdkOWIsIDB4YTY3MjU5N2QsIDB4YWRhODQwZDgsIDB4NDVmNTQ1MDQsIDB4ZmE1ZDc0MDMsIDB4ZTgzZWMzMDUsIDB4NGY5MTc1MWEsIDB4OTI1NjY5YzIsXG4gICAgMHgyM2VmZTk0MSwgMHhhOTAzZjEyZSwgMHg2MDI3MGRmMiwgMHgwMjc2ZTRiNiwgMHg5NGZkNjU3NCwgMHg5Mjc5ODViMiwgMHg4Mjc2ZGJjYiwgMHgwMjc3ODE3NixcbiAgICAweGY4YWY5MThkLCAweDRlNDhmNzllLCAweDhmNjE2ZGRmLCAweGUyOWQ4NDBlLCAweDg0MmY3ZDgzLCAweDM0MGNlNWM4LCAweDk2YmJiNjgyLCAweDkzYjRiMTQ4LFxuICAgIDB4ZWYzMDNjYWIsIDB4OTg0ZmFmMjgsIDB4Nzc5ZmFmOWIsIDB4OTJkYzU2MGQsIDB4MjI0ZDFlMjAsIDB4ODQzN2FhODgsIDB4N2QyOWRjOTYsIDB4Mjc1NmQzZGMsXG4gICAgMHg4YjkwN2NlZSwgMHhiNTFmZDI0MCwgMHhlN2MwN2NlMywgMHhlNTY2YjRhMSwgMHhjM2U5NjE1ZSwgMHgzY2Y4MjA5ZCwgMHg2MDk0ZDFlMywgMHhjZDljYTM0MSxcbiAgICAweDVjNzY0NjBlLCAweDAwZWE5ODNiLCAweGQ0ZDY3ODgxLCAweGZkNDc1NzJjLCAweGY3NmNlZGQ5LCAweGJkYTgyMjljLCAweDEyN2RhZGFhLCAweDQzOGEwNzRlLFxuICAgIDB4MWY5N2MwOTAsIDB4MDgxYmRiOGEsIDB4OTNhMDdlYmUsIDB4YjkzOGNhMTUsIDB4OTdiMDNjZmYsIDB4M2RjMmMwZjgsIDB4OGQxYWIyZWMsIDB4NjQzODBlNTEsXG4gICAgMHg2OGNjN2JmYiwgMHhkOTBmMjc4OCwgMHgxMjQ5MDE4MSwgMHg1ZGU1ZmZkNCwgMHhkZDdlZjg2YSwgMHg3NmEyZTIxNCwgMHhiOWE0MDM2OCwgMHg5MjVkOTU4ZixcbiAgICAweDRiMzlmZmZhLCAweGJhMzlhZWU5LCAweGE0ZmZkMzBiLCAweGZhZjc5MzNiLCAweDZkNDk4NjIzLCAweDE5M2NiY2ZhLCAweDI3NjI3NTQ1LCAweDgyNWNmNDdhLFxuICAgIDB4NjFiZDhiYTAsIDB4ZDExZTQyZDEsIDB4Y2VhZDA0ZjQsIDB4MTI3ZWEzOTIsIDB4MTA0MjhkYjcsIDB4ODI3MmE5NzIsIDB4OTI3MGM0YTgsIDB4MTI3ZGU1MGIsXG4gICAgMHgyODViYTFjOCwgMHgzYzYyZjQ0ZiwgMHgzNWMwZWFhNSwgMHhlODA1ZDIzMSwgMHg0Mjg5MjlmYiwgMHhiNGZjZGY4MiwgMHg0ZmI2NmE1MywgMHgwZTdkYzE1YixcbiAgICAweDFmMDgxZmFiLCAweDEwODYxOGFlLCAweGZjZmQwODZkLCAweGY5ZmYyODg5LCAweDY5NGJjYzExLCAweDIzNmE1Y2FlLCAweDEyZGVjYTRkLCAweDJjM2Y4Y2M1LFxuICAgIDB4ZDJkMDJkZmUsIDB4ZjhlZjU4OTYsIDB4ZTRjZjUyZGEsIDB4OTUxNTViNjcsIDB4NDk0YTQ4OGMsIDB4YjliNmE4MGMsIDB4NWM4ZjgyYmMsIDB4ODlkMzZiNDUsXG4gICAgMHgzYTYwOTQzNywgMHhlYzAwYzlhOSwgMHg0NDcxNTI1MywgMHgwYTg3NGI0OSwgMHhkNzczYmM0MCwgMHg3YzM0NjcxYywgMHgwMjcxN2VmNiwgMHg0ZmViNTUzNixcbiAgICAweGEyZDAyZmZmLCAweGQyYmY2MGM0LCAweGQ0M2YwM2MwLCAweDUwYjRlZjZkLCAweDA3NDc4Y2QxLCAweDAwNmUxODg4LCAweGEyZTUzZjU1LCAweGI5ZTZkNGJjLFxuICAgIDB4YTIwNDgwMTYsIDB4OTc1NzM4MzMsIDB4ZDcyMDdkNjcsIDB4ZGUwZjhmM2QsIDB4NzJmODdiMzMsIDB4YWJjYzRmMzMsIDB4NzY4OGM1NWQsIDB4N2IwMGE2YjAsXG4gICAgMHg5NDdiMDAwMSwgMHg1NzAwNzVkMiwgMHhmOWJiODhmOCwgMHg4OTQyMDE5ZSwgMHg0MjY0YTVmZiwgMHg4NTYzMDJlMCwgMHg3MmRiZDkyYiwgMHhlZTk3MWI2OSxcbiAgICAweDZlYTIyZmRlLCAweDVmMDhhZTJiLCAweGFmN2E2MTZkLCAweGU1Yzk4NzY3LCAweGNmMWZlYmQyLCAweDYxZWZjOGMyLCAweGYxYWMyNTcxLCAweGNjODIzOWMyLFxuICAgIDB4NjcyMTRjYjgsIDB4YjFlNTgzZDEsIDB4YjdkYzNlNjIsIDB4N2YxMGJkY2UsIDB4ZjkwYTVjMzgsIDB4MGZmMDQ0M2QsIDB4NjA2ZTZkYzYsIDB4NjA1NDNhNDksXG4gICAgMHg1NzI3YzE0OCwgMHgyYmU5OGExZCwgMHg4YWI0MTczOCwgMHgyMGUxYmUyNCwgMHhhZjk2ZGEwZiwgMHg2ODQ1ODQyNSwgMHg5OTgzM2JlNSwgMHg2MDBkNDU3ZCxcbiAgICAweDI4MmY5MzUwLCAweDgzMzRiMzYyLCAweGQ5MWQxMTIwLCAweDJiNmQ4ZGEwLCAweDY0MmIxZTMxLCAweDljMzA1YTAwLCAweDUyYmNlNjg4LCAweDFiMDM1ODhhLFxuICAgIDB4ZjdiYWVmZDUsIDB4NDE0MmVkOWMsIDB4YTQzMTVjMTEsIDB4ODMzMjNlYzUsIDB4ZGZlZjQ2MzYsIDB4YTEzM2M1MDEsIDB4ZTlkMzUzMWMsIDB4ZWUzNTM3ODMpO1xuXG4gIHNCb3hbM10gPSBuZXcgQXJyYXkoXG4gICAgMHg5ZGIzMDQyMCwgMHgxZmI2ZTlkZSwgMHhhN2JlN2JlZiwgMHhkMjczYTI5OCwgMHg0YTRmN2JkYiwgMHg2NGFkOGM1NywgMHg4NTUxMDQ0MywgMHhmYTAyMGVkMSxcbiAgICAweDdlMjg3YWZmLCAweGU2MGZiNjYzLCAweDA5NWYzNWExLCAweDc5ZWJmMTIwLCAweGZkMDU5ZDQzLCAweDY0OTdiN2IxLCAweGYzNjQxZjYzLCAweDI0MWU0YWRmLFxuICAgIDB4MjgxNDdmNWYsIDB4NGZhMmI4Y2QsIDB4Yzk0MzAwNDAsIDB4MGNjMzIyMjAsIDB4ZmRkMzBiMzAsIDB4YzBhNTM3NGYsIDB4MWQyZDAwZDksIDB4MjQxNDdiMTUsXG4gICAgMHhlZTRkMTExYSwgMHgwZmNhNTE2NywgMHg3MWZmOTA0YywgMHgyZDE5NWZmZSwgMHgxYTA1NjQ1ZiwgMHgwYzEzZmVmZSwgMHgwODFiMDhjYSwgMHgwNTE3MDEyMSxcbiAgICAweDgwNTMwMTAwLCAweGU4M2U1ZWZlLCAweGFjOWFmNGY4LCAweDdmZTcyNzAxLCAweGQyYjhlZTVmLCAweDA2ZGY0MjYxLCAweGJiOWU5YjhhLCAweDcyOTNlYTI1LFxuICAgIDB4Y2U4NGZmZGYsIDB4ZjU3MTg4MDEsIDB4M2RkNjRiMDQsIDB4YTI2ZjI2M2IsIDB4N2VkNDg0MDAsIDB4NTQ3ZWViZTYsIDB4NDQ2ZDRjYTAsIDB4NmNmM2Q2ZjUsXG4gICAgMHgyNjQ5YWJkZiwgMHhhZWEwYzdmNSwgMHgzNjMzOGNjMSwgMHg1MDNmN2U5MywgMHhkMzc3MjA2MSwgMHgxMWI2MzhlMSwgMHg3MjUwMGUwMywgMHhmODBlYjJiYixcbiAgICAweGFiZTA1MDJlLCAweGVjOGQ3N2RlLCAweDU3OTcxZTgxLCAweGUxNGY2NzQ2LCAweGM5MzM1NDAwLCAweDY5MjAzMThmLCAweDA4MWRiYjk5LCAweGZmYzMwNGE1LFxuICAgIDB4NGQzNTE4MDUsIDB4N2YzZDVjZTMsIDB4YTZjODY2YzYsIDB4NWQ1YmNjYTksIDB4ZGFlYzZmZWEsIDB4OWY5MjZmOTEsIDB4OWY0NjIyMmYsIDB4Mzk5MTQ2N2QsXG4gICAgMHhhNWJmNmQ4ZSwgMHgxMTQzYzQ0ZiwgMHg0Mzk1ODMwMiwgMHhkMDIxNGVlYiwgMHgwMjIwODNiOCwgMHgzZmI2MTgwYywgMHgxOGY4OTMxZSwgMHgyODE2NThlNixcbiAgICAweDI2NDg2ZTNlLCAweDhiZDc4YTcwLCAweDc0NzdlNGMxLCAweGI1MDZlMDdjLCAweGYzMmQwYTI1LCAweDc5MDk4YjAyLCAweGU0ZWFiYjgxLCAweDI4MTIzYjIzLFxuICAgIDB4NjlkZWFkMzgsIDB4MTU3NGNhMTYsIDB4ZGY4NzFiNjIsIDB4MjExYzQwYjcsIDB4YTUxYTllZjksIDB4MDAxNDM3N2IsIDB4MDQxZThhYzgsIDB4MDkxMTQwMDMsXG4gICAgMHhiZDU5ZTRkMiwgMHhlM2QxNTZkNSwgMHg0ZmU4NzZkNSwgMHgyZjkxYTM0MCwgMHg1NTdiZThkZSwgMHgwMGVhZTRhNywgMHgwY2U1YzJlYywgMHg0ZGI0YmJhNixcbiAgICAweGU3NTZiZGZmLCAweGRkMzM2OWFjLCAweGVjMTdiMDM1LCAweDA2NTcyMzI3LCAweDk5YWZjOGIwLCAweDU2YzhjMzkxLCAweDZiNjU4MTFjLCAweDVlMTQ2MTE5LFxuICAgIDB4NmU4NWNiNzUsIDB4YmUwN2MwMDIsIDB4YzIzMjU1NzcsIDB4ODkzZmY0ZWMsIDB4NWJiZmM5MmQsIDB4ZDBlYzNiMjUsIDB4Yjc4MDFhYjcsIDB4OGQ2ZDNiMjQsXG4gICAgMHgyMGM3NjNlZiwgMHhjMzY2YTVmYywgMHg5YzM4Mjg4MCwgMHgwYWNlMzIwNSwgMHhhYWM5NTQ4YSwgMHhlY2ExZDdjNywgMHgwNDFhZmEzMiwgMHgxZDE2NjI1YSxcbiAgICAweDY3MDE5MDJjLCAweDliNzU3YTU0LCAweDMxZDQ3N2Y3LCAweDkxMjZiMDMxLCAweDM2Y2M2ZmRiLCAweGM3MGI4YjQ2LCAweGQ5ZTY2YTQ4LCAweDU2ZTU1YTc5LFxuICAgIDB4MDI2YTRjZWIsIDB4NTI0MzdlZmYsIDB4MmY4Zjc2YjQsIDB4MGRmOTgwYTUsIDB4ODY3NGNkZTMsIDB4ZWRkYTA0ZWIsIDB4MTdhOWJlMDQsIDB4MmMxOGY0ZGYsXG4gICAgMHhiNzc0N2Y5ZCwgMHhhYjJhZjdiNCwgMHhlZmMzNGQyMCwgMHgyZTA5NmI3YywgMHgxNzQxYTI1NCwgMHhlNWI2YTAzNSwgMHgyMTNkNDJmNiwgMHgyYzFjN2MyNixcbiAgICAweDYxYzJmNTBmLCAweDY1NTJkYWY5LCAweGQyYzIzMWY4LCAweDI1MTMwZjY5LCAweGQ4MTY3ZmEyLCAweDA0MThmMmM4LCAweDAwMWE5NmE2LCAweDBkMTUyNmFiLFxuICAgIDB4NjMzMTVjMjEsIDB4NWUwYTcyZWMsIDB4NDliYWZlZmQsIDB4MTg3OTA4ZDksIDB4OGQwZGJkODYsIDB4MzExMTcwYTcsIDB4M2U5YjY0MGMsIDB4Y2MzZTEwZDcsXG4gICAgMHhkNWNhZDNiNiwgMHgwY2FlYzM4OCwgMHhmNzMwMDFlMSwgMHg2YzcyOGFmZiwgMHg3MWVhZTJhMSwgMHgxZjlhZjM2ZSwgMHhjZmNiZDEyZiwgMHhjMWRlODQxNyxcbiAgICAweGFjMDdiZTZiLCAweGNiNDRhMWQ4LCAweDhiOWIwZjU2LCAweDAxMzk4OGMzLCAweGIxYzUyZmNhLCAweGI0YmUzMWNkLCAweGQ4NzgyODA2LCAweDEyYTNhNGUyLFxuICAgIDB4NmY3ZGU1MzIsIDB4NThmZDdlYjYsIDB4ZDAxZWU5MDAsIDB4MjRhZGZmYzIsIDB4ZjQ5OTBmYzUsIDB4OTcxMWFhYzUsIDB4MDAxZDdiOTUsIDB4ODJlNWU3ZDIsXG4gICAgMHgxMDk4NzNmNiwgMHgwMDYxMzA5NiwgMHhjMzJkOTUyMSwgMHhhZGExMjFmZiwgMHgyOTkwODQxNSwgMHg3ZmJiOTc3ZiwgMHhhZjllYjNkYiwgMHgyOWM5ZWQyYSxcbiAgICAweDVjZTJhNDY1LCAweGE3MzBmMzJjLCAweGQwYWEzZmU4LCAweDhhNWNjMDkxLCAweGQ0OWUyY2U3LCAweDBjZTQ1NGE5LCAweGQ2MGFjZDg2LCAweDAxNWYxOTE5LFxuICAgIDB4NzcwNzkxMDMsIDB4ZGVhMDNhZjYsIDB4NzhhODU2NWUsIDB4ZGVlMzU2ZGYsIDB4MjFmMDVjYmUsIDB4OGI3NWUzODcsIDB4YjNjNTA2NTEsIDB4YjhhNWMzZWYsXG4gICAgMHhkOGVlYjZkMiwgMHhlNTIzYmU3NywgMHhjMjE1NDUyOSwgMHgyZjY5ZWZkZiwgMHhhZmU2N2FmYiwgMHhmNDcwYzRiMiwgMHhmM2UwZWI1YiwgMHhkNmNjOTg3NixcbiAgICAweDM5ZTQ0NjBjLCAweDFmZGE4NTM4LCAweDE5ODc4MzJmLCAweGNhMDA3MzY3LCAweGE5OTE0NGY4LCAweDI5NmIyOTllLCAweDQ5MmZjMjk1LCAweDkyNjZiZWFiLFxuICAgIDB4YjU2NzZlNjksIDB4OWJkM2RkZGEsIDB4ZGY3ZTA1MmYsIDB4ZGIyNTcwMWMsIDB4MWI1ZTUxZWUsIDB4ZjY1MzI0ZTYsIDB4NmFmY2UzNmMsIDB4MDMxNmNjMDQsXG4gICAgMHg4NjQ0MjEzZSwgMHhiN2RjNTlkMCwgMHg3OTY1MjkxZiwgMHhjY2Q2ZmQ0MywgMHg0MTgyMzk3OSwgMHg5MzJiY2RmNiwgMHhiNjU3YzM0ZCwgMHg0ZWRmZDI4MixcbiAgICAweDdhZTUyOTBjLCAweDNjYjk1MzZiLCAweDg1MWUyMGZlLCAweDk4MzM1NTdlLCAweDEzZWNmMGIwLCAweGQzZmZiMzcyLCAweDNmODVjNWMxLCAweDBhZWY3ZWQyKTtcblxuICBzQm94WzRdID0gbmV3IEFycmF5KFxuICAgIDB4N2VjOTBjMDQsIDB4MmM2ZTc0YjksIDB4OWIwZTY2ZGYsIDB4YTYzMzc5MTEsIDB4Yjg2YTdmZmYsIDB4MWRkMzU4ZjUsIDB4NDRkZDlkNDQsIDB4MTczMTE2N2YsXG4gICAgMHgwOGZiZjFmYSwgMHhlN2Y1MTFjYywgMHhkMjA1MWIwMCwgMHg3MzVhYmEwMCwgMHgyYWI3MjJkOCwgMHgzODYzODFjYiwgMHhhY2Y2MjQzYSwgMHg2OWJlZmQ3YSxcbiAgICAweGU2YTJlNzdmLCAweGYwYzcyMGNkLCAweGM0NDk0ODE2LCAweGNjZjVjMTgwLCAweDM4ODUxNjQwLCAweDE1YjBhODQ4LCAweGU2OGIxOGNiLCAweDRjYWFkZWZmLFxuICAgIDB4NWY0ODBhMDEsIDB4MDQxMmIyYWEsIDB4MjU5ODE0ZmMsIDB4NDFkMGVmZTIsIDB4NGU0MGI0OGQsIDB4MjQ4ZWI2ZmIsIDB4OGRiYTFjZmUsIDB4NDFhOTliMDIsXG4gICAgMHgxYTU1MGEwNCwgMHhiYThmNjVjYiwgMHg3MjUxZjRlNywgMHg5NWE1MTcyNSwgMHhjMTA2ZWNkNywgMHg5N2E1OTgwYSwgMHhjNTM5YjlhYSwgMHg0ZDc5ZmU2YSxcbiAgICAweGYyZjNmNzYzLCAweDY4YWY4MDQwLCAweGVkMGM5ZTU2LCAweDExYjQ5NThiLCAweGUxZWI1YTg4LCAweDg3MDllNmIwLCAweGQ3ZTA3MTU2LCAweDRlMjlmZWE3LFxuICAgIDB4NjM2NmU1MmQsIDB4MDJkMWMwMDAsIDB4YzRhYzhlMDUsIDB4OTM3N2Y1NzEsIDB4MGMwNTM3MmEsIDB4NTc4NTM1ZjIsIDB4MjI2MWJlMDIsIDB4ZDY0MmEwYzksXG4gICAgMHhkZjEzYTI4MCwgMHg3NGI1NWJkMiwgMHg2ODIxOTljMCwgMHhkNDIxZTVlYywgMHg1M2ZiM2NlOCwgMHhjOGFkZWRiMywgMHgyOGE4N2ZjOSwgMHgzZDk1OTk4MSxcbiAgICAweDVjMWZmOTAwLCAweGZlMzhkMzk5LCAweDBjNGVmZjBiLCAweDA2MjQwN2VhLCAweGFhMmY0ZmIxLCAweDRmYjk2OTc2LCAweDkwYzc5NTA1LCAweGIwYThhNzc0LFxuICAgIDB4ZWY1NWExZmYsIDB4ZTU5Y2EyYzIsIDB4YTZiNjJkMjcsIDB4ZTY2YTQyNjMsIDB4ZGY2NTAwMWYsIDB4MGVjNTA5NjYsIDB4ZGZkZDU1YmMsIDB4MjlkZTA2NTUsXG4gICAgMHg5MTFlNzM5YSwgMHgxN2FmODk3NSwgMHgzMmM3OTExYywgMHg4OWY4OTQ2OCwgMHgwZDAxZTk4MCwgMHg1MjQ3NTVmNCwgMHgwM2I2M2NjOSwgMHgwY2M4NDRiMixcbiAgICAweGJjZjNmMGFhLCAweDg3YWMzNmU5LCAweGU1M2E3NDI2LCAweDAxYjNkODJiLCAweDFhOWU3NDQ5LCAweDY0ZWUyZDdlLCAweGNkZGJiMWRhLCAweDAxYzk0OTEwLFxuICAgIDB4Yjg2OGJmODAsIDB4MGQyNmYzZmQsIDB4OTM0MmVkZTcsIDB4MDRhNWMyODQsIDB4NjM2NzM3YjYsIDB4NTBmNWI2MTYsIDB4ZjI0NzY2ZTMsIDB4OGVjYTM2YzEsXG4gICAgMHgxMzZlMDVkYiwgMHhmZWYxODM5MSwgMHhmYjg4N2EzNywgMHhkNmU3ZjdkNCwgMHhjN2ZiN2RjOSwgMHgzMDYzZmNkZiwgMHhiNmY1ODlkZSwgMHhlYzI5NDFkYSxcbiAgICAweDI2ZTQ2Njk1LCAweGI3NTY2NDE5LCAweGY2NTRlZmM1LCAweGQwOGQ1OGI3LCAweDQ4OTI1NDAxLCAweGMxYmFjYjdmLCAweGU1ZmY1NTBmLCAweGI2MDgzMDQ5LFxuICAgIDB4NWJiNWQwZTgsIDB4ODdkNzJlNWEsIDB4YWI2YTZlZTEsIDB4MjIzYTY2Y2UsIDB4YzYyYmYzY2QsIDB4OWUwODg1ZjksIDB4NjhjYjNlNDcsIDB4MDg2YzAxMGYsXG4gICAgMHhhMjFkZTgyMCwgMHhkMThiNjlkZSwgMHhmM2Y2NTc3NywgMHhmYTAyYzNmNiwgMHg0MDdlZGFjMywgMHhjYmIzZDU1MCwgMHgxNzkzMDg0ZCwgMHhiMGQ3MGViYSxcbiAgICAweDBhYjM3OGQ1LCAweGQ5NTFmYjBjLCAweGRlZDdkYTU2LCAweDQxMjRiYmU0LCAweDk0Y2EwYjU2LCAweDBmNTc1NWQxLCAweGUwZTFlNTZlLCAweDYxODRiNWJlLFxuICAgIDB4NTgwYTI0OWYsIDB4OTRmNzRiYzAsIDB4ZTMyNzg4OGUsIDB4OWY3YjU1NjEsIDB4YzNkYzAyODAsIDB4MDU2ODc3MTUsIDB4NjQ2YzZiZDcsIDB4NDQ5MDRkYjMsXG4gICAgMHg2NmI0ZjBhMywgMHhjMGYxNjQ4YSwgMHg2OTdlZDVhZiwgMHg0OWU5MmZmNiwgMHgzMDllMzc0ZiwgMHgyY2I2MzU2YSwgMHg4NTgwODU3MywgMHg0OTkxZjg0MCxcbiAgICAweDc2ZjBhZTAyLCAweDA4M2JlODRkLCAweDI4NDIxYzlhLCAweDQ0NDg5NDA2LCAweDczNmU0Y2I4LCAweGMxMDkyOTEwLCAweDhiYzk1ZmM2LCAweDdkODY5Y2Y0LFxuICAgIDB4MTM0ZjYxNmYsIDB4MmU3NzExOGQsIDB4YjMxYjJiZTEsIDB4YWE5MGI0NzIsIDB4M2NhNWQ3MTcsIDB4N2QxNjFiYmEsIDB4OWNhZDkwMTAsIDB4YWY0NjJiYTIsXG4gICAgMHg5ZmU0NTlkMiwgMHg0NWQzNDU1OSwgMHhkOWYyZGExMywgMHhkYmM2NTQ4NywgMHhmM2U0Zjk0ZSwgMHgxNzZkNDg2ZiwgMHgwOTdjMTNlYSwgMHg2MzFkYTVjNyxcbiAgICAweDQ0NWY3MzgyLCAweDE3NTY4M2Y0LCAweGNkYzY2YTk3LCAweDcwYmUwMjg4LCAweGIzY2RjZjcyLCAweDZlNWRkMmYzLCAweDIwOTM2MDc5LCAweDQ1OWI4MGE1LFxuICAgIDB4YmU2MGUyZGIsIDB4YTljMjMxMDEsIDB4ZWJhNTMxNWMsIDB4MjI0ZTQyZjIsIDB4MWM1YzE1NzIsIDB4ZjY3MjFiMmMsIDB4MWFkMmZmZjMsIDB4OGMyNTQwNGUsXG4gICAgMHgzMjRlZDcyZiwgMHg0MDY3YjdmZCwgMHgwNTIzMTM4ZSwgMHg1Y2EzYmM3OCwgMHhkYzBmZDY2ZSwgMHg3NTkyMjI4MywgMHg3ODRkNmIxNywgMHg1OGViYjE2ZSxcbiAgICAweDQ0MDk0Zjg1LCAweDNmNDgxZDg3LCAweGZjZmVhZTdiLCAweDc3YjVmZjc2LCAweDhjMjMwMmJmLCAweGFhZjQ3NTU2LCAweDVmNDZiMDJhLCAweDJiMDkyODAxLFxuICAgIDB4M2QzOGY1ZjcsIDB4MGNhODFmMzYsIDB4NTJhZjRhOGEsIDB4NjZkNWU3YzAsIDB4ZGYzYjA4NzQsIDB4OTUwNTUxMTAsIDB4MWI1YWQ3YTgsIDB4ZjYxZWQ1YWQsXG4gICAgMHg2Y2Y2ZTQ3OSwgMHgyMDc1ODE4NCwgMHhkMGNlZmE2NSwgMHg4OGY3YmU1OCwgMHg0YTA0NjgyNiwgMHgwZmY2ZjhmMywgMHhhMDljN2Y3MCwgMHg1MzQ2YWJhMCxcbiAgICAweDVjZTk2YzI4LCAweGUxNzZlZGEzLCAweDZiYWMzMDdmLCAweDM3NjgyOWQyLCAweDg1MzYwZmE5LCAweDE3ZTNmZTJhLCAweDI0Yjc5NzY3LCAweGY1YTk2YjIwLFxuICAgIDB4ZDZjZDI1OTUsIDB4NjhmZjFlYmYsIDB4NzU1NTQ0MmMsIDB4ZjE5ZjA2YmUsIDB4ZjllMDY1OWEsIDB4ZWViOTQ5MWQsIDB4MzQwMTA3MTgsIDB4YmIzMGNhYjgsXG4gICAgMHhlODIyZmUxNSwgMHg4ODU3MDk4MywgMHg3NTBlNjI0OSwgMHhkYTYyN2U1NSwgMHg1ZTc2ZmZhOCwgMHhiMTUzNDU0NiwgMHg2ZDQ3ZGUwOCwgMHhlZmU5ZTdkNCk7XG5cbiAgc0JveFs1XSA9IG5ldyBBcnJheShcbiAgICAweGY2ZmE4ZjlkLCAweDJjYWM2Y2UxLCAweDRjYTM0ODY3LCAweGUyMzM3ZjdjLCAweDk1ZGIwOGU3LCAweDAxNjg0M2I0LCAweGVjZWQ1Y2JjLCAweDMyNTU1M2FjLFxuICAgIDB4YmY5ZjA5NjAsIDB4ZGZhMWUyZWQsIDB4ODNmMDU3OWQsIDB4NjNlZDg2YjksIDB4MWFiNmE2YjgsIDB4ZGU1ZWJlMzksIDB4ZjM4ZmY3MzIsIDB4ODk4OWIxMzgsXG4gICAgMHgzM2YxNDk2MSwgMHhjMDE5MzdiZCwgMHhmNTA2YzZkYSwgMHhlNDYyNWU3ZSwgMHhhMzA4ZWE5OSwgMHg0ZTIzZTMzYywgMHg3OWNiZDdjYywgMHg0OGExNDM2NyxcbiAgICAweGEzMTQ5NjE5LCAweGZlYzk0YmQ1LCAweGExMTQxNzRhLCAweGVhYTAxODY2LCAweGEwODRkYjJkLCAweDA5YTg0ODZmLCAweGE4ODg2MTRhLCAweDI5MDBhZjk4LFxuICAgIDB4MDE2NjU5OTEsIDB4ZTE5OTI4NjMsIDB4YzhmMzBjNjAsIDB4MmU3OGVmM2MsIDB4ZDBkNTE5MzIsIDB4Y2YwZmVjMTQsIDB4ZjdjYTA3ZDIsIDB4ZDBhODIwNzIsXG4gICAgMHhmZDQxMTk3ZSwgMHg5MzA1YTZiMCwgMHhlODZiZTNkYSwgMHg3NGJlZDNjZCwgMHgzNzJkYTUzYywgMHg0YzdmNDQ0OCwgMHhkYWI1ZDQ0MCwgMHg2ZGJhMGVjMyxcbiAgICAweDA4MzkxOWE3LCAweDlmYmFlZWQ5LCAweDQ5ZGJjZmIwLCAweDRlNjcwYzUzLCAweDVjM2Q5YzAxLCAweDY0YmRiOTQxLCAweDJjMGU2MzZhLCAweGJhN2RkOWNkLFxuICAgIDB4ZWE2ZjczODgsIDB4ZTcwYmM3NjIsIDB4MzVmMjlhZGIsIDB4NWM0Y2RkOGQsIDB4ZjBkNDhkOGMsIDB4Yjg4MTUzZTIsIDB4MDhhMTk4NjYsIDB4MWFlMmVhYzgsXG4gICAgMHgyODRjYWY4OSwgMHhhYTkyODIyMywgMHg5MzM0YmU1MywgMHgzYjNhMjFiZiwgMHgxNjQzNGJlMywgMHg5YWVhMzkwNiwgMHhlZmU4YzM2ZSwgMHhmODkwY2RkOSxcbiAgICAweDgwMjI2ZGFlLCAweGMzNDBhNGEzLCAweGRmN2U5YzA5LCAweGE2OTRhODA3LCAweDViN2M1ZWNjLCAweDIyMWRiM2E2LCAweDlhNjlhMDJmLCAweDY4ODE4YTU0LFxuICAgIDB4Y2ViMjI5NmYsIDB4NTNjMDg0M2EsIDB4ZmU4OTM2NTUsIDB4MjViZmU2OGEsIDB4YjQ2MjhhYmMsIDB4Y2YyMjJlYmYsIDB4MjVhYzZmNDgsIDB4YTlhOTkzODcsXG4gICAgMHg1M2JkZGI2NSwgMHhlNzZmZmJlNywgMHhlOTY3ZmQ3OCwgMHgwYmE5MzU2MywgMHg4ZTM0MmJjMSwgMHhlOGExMWJlOSwgMHg0OTgwNzQwZCwgMHhjODA4N2RmYyxcbiAgICAweDhkZTRiZjk5LCAweGExMTEwMWEwLCAweDdmZDM3OTc1LCAweGRhNWEyNmMwLCAweGU4MWY5OTRmLCAweDk1MjhjZDg5LCAweGZkMzM5ZmVkLCAweGI4NzgzNGJmLFxuICAgIDB4NWYwNDQ1NmQsIDB4MjIyNTg2OTgsIDB4YzljNGM4M2IsIDB4MmRjMTU2YmUsIDB4NGY2MjhkYWEsIDB4NTdmNTVlYzUsIDB4ZTIyMjBhYmUsIDB4ZDI5MTZlYmYsXG4gICAgMHg0ZWM3NWI5NSwgMHgyNGYyYzNjMCwgMHg0MmQxNWQ5OSwgMHhjZDBkN2ZhMCwgMHg3YjZlMjdmZiwgMHhhOGRjOGFmMCwgMHg3MzQ1YzEwNiwgMHhmNDFlMjMyZixcbiAgICAweDM1MTYyMzg2LCAweGU2ZWE4OTI2LCAweDMzMzNiMDk0LCAweDE1N2VjNmYyLCAweDM3MmI3NGFmLCAweDY5MjU3M2U0LCAweGU5YTlkODQ4LCAweGYzMTYwMjg5LFxuICAgIDB4M2E2MmVmMWQsIDB4YTc4N2UyMzgsIDB4ZjNhNWY2NzYsIDB4NzQzNjQ4NTMsIDB4MjA5NTEwNjMsIDB4NDU3NjY5OGQsIDB4YjZmYWQ0MDcsIDB4NTkyYWY5NTAsXG4gICAgMHgzNmY3MzUyMywgMHg0Y2ZiNmU4NywgMHg3ZGE0Y2VjMCwgMHg2YzE1MmRhYSwgMHhjYjAzOTZhOCwgMHhjNTBkZmU1ZCwgMHhmY2Q3MDdhYiwgMHgwOTIxYzQyZixcbiAgICAweDg5ZGZmMGJiLCAweDVmZTJiZTc4LCAweDQ0OGY0ZjMzLCAweDc1NDYxM2M5LCAweDJiMDVkMDhkLCAweDQ4YjlkNTg1LCAweGRjMDQ5NDQxLCAweGM4MDk4ZjliLFxuICAgIDB4N2RlZGU3ODYsIDB4YzM5YTMzNzMsIDB4NDI0MTAwMDUsIDB4NmEwOTE3NTEsIDB4MGVmM2M4YTYsIDB4ODkwMDcyZDYsIDB4MjgyMDc2ODIsIDB4YTlhOWY3YmUsXG4gICAgMHhiZjMyNjc5ZCwgMHhkNDViNWI3NSwgMHhiMzUzZmQwMCwgMHhjYmIwZTM1OCwgMHg4MzBmMjIwYSwgMHgxZjhmYjIxNCwgMHhkMzcyY2YwOCwgMHhjYzNjNGExMyxcbiAgICAweDhjZjYzMTY2LCAweDA2MWM4N2JlLCAweDg4Yzk4Zjg4LCAweDYwNjJlMzk3LCAweDQ3Y2Y4ZTdhLCAweGI2Yzg1MjgzLCAweDNjYzJhY2ZiLCAweDNmYzA2OTc2LFxuICAgIDB4NGU4ZjAyNTIsIDB4NjRkODMxNGQsIDB4ZGEzODcwZTMsIDB4MWU2NjU0NTksIDB4YzEwOTA4ZjAsIDB4NTEzMDIxYTUsIDB4NmM1YjY4YjcsIDB4ODIyZjhhYTAsXG4gICAgMHgzMDA3Y2QzZSwgMHg3NDcxOWVlZiwgMHhkYzg3MjY4MSwgMHgwNzMzNDBkNCwgMHg3ZTQzMmZkOSwgMHgwYzVlYzI0MSwgMHg4ODA5Mjg2YywgMHhmNTkyZDg5MSxcbiAgICAweDA4YTkzMGY2LCAweDk1N2VmMzA1LCAweGI3ZmJmZmJkLCAweGMyNjZlOTZmLCAweDZmZTRhYzk4LCAweGIxNzNlY2MwLCAweGJjNjBiNDJhLCAweDk1MzQ5OGRhLFxuICAgIDB4ZmJhMWFlMTIsIDB4MmQ0YmQ3MzYsIDB4MGYyNWZhYWIsIDB4YTRmM2ZjZWIsIDB4ZTI5NjkxMjMsIDB4MjU3ZjBjM2QsIDB4OTM0OGFmNDksIDB4MzYxNDAwYmMsXG4gICAgMHhlODgxNmY0YSwgMHgzODE0ZjIwMCwgMHhhM2Y5NDA0MywgMHg5YzdhNTRjMiwgMHhiYzcwNGY1NywgMHhkYTQxZTdmOSwgMHhjMjVhZDMzYSwgMHg1NGY0YTA4NCxcbiAgICAweGIxN2Y1NTA1LCAweDU5MzU3Y2JlLCAweGVkYmQxNWM4LCAweDdmOTdjNWFiLCAweGJhNWFjN2I1LCAweGI2ZjZkZWFmLCAweDNhNDc5YzNhLCAweDUzMDJkYTI1LFxuICAgIDB4NjUzZDdlNmEsIDB4NTQyNjhkNDksIDB4NTFhNDc3ZWEsIDB4NTAxN2Q1NWIsIDB4ZDdkMjVkODgsIDB4NDQxMzZjNzYsIDB4MDQwNGE4YzgsIDB4YjhlNWExMjEsXG4gICAgMHhiODFhOTI4YSwgMHg2MGVkNTg2OSwgMHg5N2M1NWI5NiwgMHhlYWVjOTkxYiwgMHgyOTkzNTkxMywgMHgwMWZkYjdmMSwgMHgwODhlOGRmYSwgMHg5YWI2ZjZmNSxcbiAgICAweDNiNGNiZjlmLCAweDRhNWRlM2FiLCAweGU2MDUxZDM1LCAweGEwZTFkODU1LCAweGQzNmI0Y2YxLCAweGY1NDRlZGViLCAweGIwZTkzNTI0LCAweGJlYmI4ZmJkLFxuICAgIDB4YTJkNzYyY2YsIDB4NDljOTJmNTQsIDB4MzhiNWYzMzEsIDB4NzEyOGE0NTQsIDB4NDgzOTI5MDUsIDB4YTY1YjFkYjgsIDB4ODUxYzk3YmQsIDB4ZDY3NWNmMmYpO1xuXG4gIHNCb3hbNl0gPSBuZXcgQXJyYXkoXG4gICAgMHg4NWUwNDAxOSwgMHgzMzJiZjU2NywgMHg2NjJkYmZmZiwgMHhjZmM2NTY5MywgMHgyYThkN2Y2ZiwgMHhhYjliYzkxMiwgMHhkZTYwMDhhMSwgMHgyMDI4ZGExZixcbiAgICAweDAyMjdiY2U3LCAweDRkNjQyOTE2LCAweDE4ZmFjMzAwLCAweDUwZjE4YjgyLCAweDJjYjJjYjExLCAweGIyMzJlNzVjLCAweDRiMzY5NWYyLCAweGIyODcwN2RlLFxuICAgIDB4YTA1ZmJjZjYsIDB4Y2Q0MTgxZTksIDB4ZTE1MDIxMGMsIDB4ZTI0ZWYxYmQsIDB4YjE2OGMzODEsIDB4ZmRlNGU3ODksIDB4NWM3OWIwZDgsIDB4MWU4YmZkNDMsXG4gICAgMHg0ZDQ5NTAwMSwgMHgzOGJlNDM0MSwgMHg5MTNjZWUxZCwgMHg5MmE3OWMzZiwgMHgwODk3NjZiZSwgMHhiYWVlYWRmNCwgMHgxMjg2YmVjZiwgMHhiNmVhY2IxOSxcbiAgICAweDI2NjBjMjAwLCAweDc1NjViZGU0LCAweDY0MjQxZjdhLCAweDgyNDhkY2E5LCAweGMzYjNhZDY2LCAweDI4MTM2MDg2LCAweDBiZDhkZmE4LCAweDM1NmQxY2YyLFxuICAgIDB4MTA3Nzg5YmUsIDB4YjNiMmU5Y2UsIDB4MDUwMmFhOGYsIDB4MGJjMDM1MWUsIDB4MTY2YmY1MmEsIDB4ZWIxMmZmODIsIDB4ZTM0ODY5MTEsIDB4ZDM0ZDc1MTYsXG4gICAgMHg0ZTdiM2FmZiwgMHg1ZjQzNjcxYiwgMHg5Y2Y2ZTAzNywgMHg0OTgxYWM4MywgMHgzMzQyNjZjZSwgMHg4YzkzNDFiNywgMHhkMGQ4NTRjMCwgMHhjYjNhNmM4OCxcbiAgICAweDQ3YmMyODI5LCAweDQ3MjViYTM3LCAweGE2NmFkMjJiLCAweDdhZDYxZjFlLCAweDBjNWNiYWZhLCAweDQ0MzdmMTA3LCAweGI2ZTc5OTYyLCAweDQyZDJkODE2LFxuICAgIDB4MGE5NjEyODgsIDB4ZTFhNWMwNmUsIDB4MTM3NDllNjcsIDB4NzJmYzA4MWEsIDB4YjFkMTM5ZjcsIDB4Zjk1ODM3NDUsIDB4Y2YxOWRmNTgsIDB4YmVjM2Y3NTYsXG4gICAgMHhjMDZlYmEzMCwgMHgwNzIxMWIyNCwgMHg0NWMyODgyOSwgMHhjOTVlMzE3ZiwgMHhiYzhlYzUxMSwgMHgzOGJjNDZlOSwgMHhjNmU2ZmExNCwgMHhiYWU4NTg0YSxcbiAgICAweGFkNGViYzQ2LCAweDQ2OGY1MDhiLCAweDc4Mjk0MzVmLCAweGYxMjQxODNiLCAweDgyMWRiYTlmLCAweGFmZjYwZmY0LCAweGVhMmM0ZTZkLCAweDE2ZTM5MjY0LFxuICAgIDB4OTI1NDRhOGIsIDB4MDA5YjRmYzMsIDB4YWJhNjhjZWQsIDB4OWFjOTZmNzgsIDB4MDZhNWI3OWEsIDB4YjI4NTZlNmUsIDB4MWFlYzNjYTksIDB4YmU4Mzg2ODgsXG4gICAgMHgwZTA4MDRlOSwgMHg1NWYxYmU1NiwgMHhlN2U1MzYzYiwgMHhiM2ExZjI1ZCwgMHhmN2RlYmI4NSwgMHg2MWZlMDMzYywgMHgxNjc0NjIzMywgMHgzYzAzNGMyOCxcbiAgICAweGRhNmQwYzc0LCAweDc5YWFjNTZjLCAweDNjZTRlMWFkLCAweDUxZjBjODAyLCAweDk4ZjhmMzVhLCAweDE2MjZhNDlmLCAweGVlZDgyYjI5LCAweDFkMzgyZmUzLFxuICAgIDB4MGM0ZmI5OWEsIDB4YmIzMjU3NzgsIDB4M2VjNmQ5N2IsIDB4NmU3N2E2YTksIDB4Y2I2NThiNWMsIDB4ZDQ1MjMwYzcsIDB4MmJkMTQwOGIsIDB4NjBjMDNlYjcsXG4gICAgMHhiOTA2OGQ3OCwgMHhhMzM3NTRmNCwgMHhmNDMwYzg3ZCwgMHhjOGE3MTMwMiwgMHhiOTZkOGMzMiwgMHhlYmQ0ZTdiZSwgMHhiZThiOWQyZCwgMHg3OTc5ZmIwNixcbiAgICAweGU3MjI1MzA4LCAweDhiNzVjZjc3LCAweDExZWY4ZGE0LCAweGUwODNjODU4LCAweDhkNmI3ODZmLCAweDVhNjMxN2E2LCAweGZhNWNmN2EwLCAweDVkZGEwMDMzLFxuICAgIDB4ZjI4ZWJmYjAsIDB4ZjViOWMzMTAsIDB4YTBlYWMyODAsIDB4MDhiOTc2N2EsIDB4YTNkOWQyYjAsIDB4NzlkMzQyMTcsIDB4MDIxYTcxOGQsIDB4OWFjNjMzNmEsXG4gICAgMHgyNzExZmQ2MCwgMHg0MzgwNTBlMywgMHgwNjk5MDhhOCwgMHgzZDdmZWRjNCwgMHg4MjZkMmJlZiwgMHg0ZWViODQ3NiwgMHg0ODhkY2YyNSwgMHgzNmM5ZDU2NixcbiAgICAweDI4ZTc0ZTQxLCAweGMyNjEwYWNhLCAweDNkNDlhOWNmLCAweGJhZTNiOWRmLCAweGI2NWY4ZGU2LCAweDkyYWVhZjY0LCAweDNhYzdkNWU2LCAweDllYTgwNTA5LFxuICAgIDB4ZjIyYjAxN2QsIDB4YTQxNzNmNzAsIDB4ZGQxZTE2YzMsIDB4MTVlMGQ3ZjksIDB4NTBiMWI4ODcsIDB4MmI5ZjRmZDUsIDB4NjI1YWJhODIsIDB4NmEwMTc5NjIsXG4gICAgMHgyZWMwMWI5YywgMHgxNTQ4OGFhOSwgMHhkNzE2ZTc0MCwgMHg0MDA1NWEyYywgMHg5M2QyOWEyMiwgMHhlMzJkYmY5YSwgMHgwNTg3NDViOSwgMHgzNDUzZGMxZSxcbiAgICAweGQ2OTkyOTZlLCAweDQ5NmNmZjZmLCAweDFjOWY0OTg2LCAweGRmZTJlZDA3LCAweGI4NzI0MmQxLCAweDE5ZGU3ZWFlLCAweDA1M2U1NjFhLCAweDE1YWQ2ZjhjLFxuICAgIDB4NjY2MjZjMWMsIDB4NzE1NGMyNGMsIDB4ZWEwODJiMmEsIDB4OTNlYjI5MzksIDB4MTdkY2IwZjAsIDB4NThkNGYyYWUsIDB4OWVhMjk0ZmIsIDB4NTJjZjU2NGMsXG4gICAgMHg5ODgzZmU2NiwgMHgyZWM0MDU4MSwgMHg3NjM5NTNjMywgMHgwMWQ2NjkyZSwgMHhkM2EwYzEwOCwgMHhhMWU3MTYwZSwgMHhlNGYyZGZhNiwgMHg2OTNlZDI4NSxcbiAgICAweDc0OTA0Njk4LCAweDRjMmIwZWRkLCAweDRmNzU3NjU2LCAweDVkMzkzMzc4LCAweGExMzIyMzRmLCAweDNkMzIxYzVkLCAweGMzZjVlMTk0LCAweDRiMjY5MzAxLFxuICAgIDB4Yzc5ZjAyMmYsIDB4M2M5OTdlN2UsIDB4NWU0Zjk1MDQsIDB4M2ZmYWZiYmQsIDB4NzZmN2FkMGUsIDB4Mjk2NjkzZjQsIDB4M2QxZmNlNmYsIDB4YzYxZTQ1YmUsXG4gICAgMHhkM2I1YWIzNCwgMHhmNzJiZjliNywgMHgxYjA0MzRjMCwgMHg0ZTcyYjU2NywgMHg1NTkyYTMzZCwgMHhiNTIyOTMwMSwgMHhjZmQyYTg3ZiwgMHg2MGFlYjc2NyxcbiAgICAweDE4MTQzODZiLCAweDMwYmNjMzNkLCAweDM4YTBjMDdkLCAweGZkMTYwNmYyLCAweGMzNjM1MTliLCAweDU4OWRkMzkwLCAweDU0NzlmOGU2LCAweDFjYjhkNjQ3LFxuICAgIDB4OTdmZDYxYTksIDB4ZWE3NzU5ZjQsIDB4MmQ1NzUzOWQsIDB4NTY5YTU4Y2YsIDB4ZTg0ZTYzYWQsIDB4NDYyZTFiNzgsIDB4NjU4MGY4N2UsIDB4ZjM4MTc5MTQsXG4gICAgMHg5MWRhNTVmNCwgMHg0MGEyMzBmMywgMHhkMTk4OGYzNSwgMHhiNmUzMThkMiwgMHgzZmZhNTBiYywgMHgzZDQwZjAyMSwgMHhjM2MwYmRhZSwgMHg0OTU4YzI0YyxcbiAgICAweDUxOGYzNmIyLCAweDg0YjFkMzcwLCAweDBmZWRjZTgzLCAweDg3OGRkYWRhLCAweGYyYTI3OWM3LCAweDk0ZTAxYmU4LCAweDkwNzE2ZjRiLCAweDk1NGI4YWEzKTtcblxuICBzQm94WzddID0gbmV3IEFycmF5KFxuICAgIDB4ZTIxNjMwMGQsIDB4YmJkZGZmZmMsIDB4YTdlYmRhYmQsIDB4MzU2NDgwOTUsIDB4Nzc4OWY4YjcsIDB4ZTZjMTEyMWIsIDB4MGUyNDE2MDAsIDB4MDUyY2U4YjUsXG4gICAgMHgxMWE5Y2ZiMCwgMHhlNTk1MmYxMSwgMHhlY2U3OTkwYSwgMHg5Mzg2ZDE3NCwgMHgyYTQyOTMxYywgMHg3NmUzODExMSwgMHhiMTJkZWYzYSwgMHgzN2RkZGRmYyxcbiAgICAweGRlOWFkZWIxLCAweDBhMGNjMzJjLCAweGJlMTk3MDI5LCAweDg0YTAwOTQwLCAweGJiMjQzYTBmLCAweGI0ZDEzN2NmLCAweGI0NGU3OWYwLCAweDA0OWVlZGZkLFxuICAgIDB4MGIxNWExNWQsIDB4NDgwZDMxNjgsIDB4OGJiYmRlNWEsIDB4NjY5ZGVkNDIsIDB4YzdlY2U4MzEsIDB4M2Y4Zjk1ZTcsIDB4NzJkZjE5MWIsIDB4NzU4MDMzMGQsXG4gICAgMHg5NDA3NDI1MSwgMHg1YzdkY2RmYSwgMHhhYmJlNmQ2MywgMHhhYTQwMjE2NCwgMHhiMzAxZDQwYSwgMHgwMmU3ZDFjYSwgMHg1MzU3MWRhZSwgMHg3YTMxODJhMixcbiAgICAweDEyYThkZGVjLCAweGZkYWEzMzVkLCAweDE3NmY0M2U4LCAweDcxZmI0NmQ0LCAweDM4MTI5MDIyLCAweGNlOTQ5YWQ0LCAweGI4NDc2OWFkLCAweDk2NWJkODYyLFxuICAgIDB4ODJmM2QwNTUsIDB4NjZmYjk3NjcsIDB4MTViODBiNGUsIDB4MWQ1YjQ3YTAsIDB4NGNmZGUwNmYsIDB4YzI4ZWM0YjgsIDB4NTdlODcyNmUsIDB4NjQ3YTc4ZmMsXG4gICAgMHg5OTg2NWQ0NCwgMHg2MDhiZDU5MywgMHg2YzIwMGUwMywgMHgzOWRjNWZmNiwgMHg1ZDBiMDBhMywgMHhhZTYzYWZmMiwgMHg3ZThiZDYzMiwgMHg3MDEwOGMwYyxcbiAgICAweGJiZDM1MDQ5LCAweDI5OThkZjA0LCAweDk4MGNmNDJhLCAweDliNmRmNDkxLCAweDllN2VkZDUzLCAweDA2OTE4NTQ4LCAweDU4Y2I3ZTA3LCAweDNiNzRlZjJlLFxuICAgIDB4NTIyZmZmYjEsIDB4ZDI0NzA4Y2MsIDB4MWM3ZTI3Y2QsIDB4YTRlYjIxNWIsIDB4M2NmMWQyZTIsIDB4MTliNDdhMzgsIDB4NDI0Zjc2MTgsIDB4MzU4NTYwMzksXG4gICAgMHg5ZDE3ZGVlNywgMHgyN2ViMzVlNiwgMHhjOWFmZjY3YiwgMHgzNmJhZjViOCwgMHgwOWM0NjdjZCwgMHhjMTg5MTBiMSwgMHhlMTFkYmY3YiwgMHgwNmNkMWFmOCxcbiAgICAweDcxNzBjNjA4LCAweDJkNWUzMzU0LCAweGQ0ZGU0OTVhLCAweDY0YzZkMDA2LCAweGJjYzBjNjJjLCAweDNkZDAwZGIzLCAweDcwOGY4ZjM0LCAweDc3ZDUxYjQyLFxuICAgIDB4MjY0ZjYyMGYsIDB4MjRiOGQyYmYsIDB4MTVjMWI3OWUsIDB4NDZhNTI1NjQsIDB4ZjhkN2U1NGUsIDB4M2UzNzgxNjAsIDB4Nzg5NWNkYTUsIDB4ODU5YzE1YTUsXG4gICAgMHhlNjQ1OTc4OCwgMHhjMzdiYzc1ZiwgMHhkYjA3YmEwYywgMHgwNjc2YTNhYiwgMHg3ZjIyOWIxZSwgMHgzMTg0MmU3YiwgMHgyNDI1OWZkNywgMHhmOGJlZjQ3MixcbiAgICAweDgzNWZmY2I4LCAweDZkZjRjMWYyLCAweDk2ZjViMTk1LCAweGZkMGFmMGZjLCAweGIwZmUxMzRjLCAweGUyNTA2ZDNkLCAweDRmOWIxMmVhLCAweGYyMTVmMjI1LFxuICAgIDB4YTIyMzczNmYsIDB4OWZiNGM0MjgsIDB4MjVkMDQ5NzksIDB4MzRjNzEzZjgsIDB4YzQ2MTgxODcsIDB4ZWE3YTZlOTgsIDB4N2NkMTZlZmMsIDB4MTQzNjg3NmMsXG4gICAgMHhmMTU0NDEwNywgMHhiZWRlZWUxNCwgMHg1NmU5YWYyNywgMHhhMDRhYTQ0MSwgMHgzY2Y3Yzg5OSwgMHg5MmVjYmFlNiwgMHhkZDY3MDE2ZCwgMHgxNTE2ODJlYixcbiAgICAweGE4NDJlZWRmLCAweGZkYmE2MGI0LCAweGYxOTA3Yjc1LCAweDIwZTMwMzBmLCAweDI0ZDhjMjllLCAweGUxMzk2NzNiLCAweGVmYTYzZmI4LCAweDcxODczMDU0LFxuICAgIDB4YjZmMmNmM2IsIDB4OWYzMjY0NDIsIDB4Y2IxNWE0Y2MsIDB4YjAxYTQ1MDQsIDB4ZjFlNDdkOGQsIDB4ODQ0YTFiZTUsIDB4YmFlN2RmZGMsIDB4NDJjYmRhNzAsXG4gICAgMHhjZDdkYWUwYSwgMHg1N2U4NWI3YSwgMHhkNTNmNWFmNiwgMHgyMGNmNGQ4YywgMHhjZWE0ZDQyOCwgMHg3OWQxMzBhNCwgMHgzNDg2ZWJmYiwgMHgzM2QzY2RkYyxcbiAgICAweDc3ODUzYjUzLCAweDM3ZWZmY2I1LCAweGM1MDY4Nzc4LCAweGU1ODBiM2U2LCAweDRlNjhiOGY0LCAweGM1YzhiMzdlLCAweDBkODA5ZWEyLCAweDM5OGZlYjdjLFxuICAgIDB4MTMyYTRmOTQsIDB4NDNiNzk1MGUsIDB4MmZlZTdkMWMsIDB4MjIzNjEzYmQsIDB4ZGQwNmNhYTIsIDB4MzdkZjkzMmIsIDB4YzQyNDgyODksIDB4YWNmM2ViYzMsXG4gICAgMHg1NzE1ZjZiNywgMHhlZjM0NzhkZCwgMHhmMjY3NjE2ZiwgMHhjMTQ4Y2JlNCwgMHg5MDUyODE1ZSwgMHg1ZTQxMGZhYiwgMHhiNDhhMjQ2NSwgMHgyZWRhN2ZhNCxcbiAgICAweGU4N2I0MGU0LCAweGU5OGVhMDg0LCAweDU4ODllOWUxLCAweGVmZDM5MGZjLCAweGRkMDdkMzViLCAweGRiNDg1Njk0LCAweDM4ZDdlNWIyLCAweDU3NzIwMTAxLFxuICAgIDB4NzMwZWRlYmMsIDB4NWI2NDMxMTMsIDB4OTQ5MTdlNGYsIDB4NTAzYzJmYmEsIDB4NjQ2ZjEyODIsIDB4NzUyM2QyNGEsIDB4ZTA3Nzk2OTUsIDB4ZjljMTdhOGYsXG4gICAgMHg3YTViMjEyMSwgMHhkMTg3Yjg5NiwgMHgyOTI2M2E0ZCwgMHhiYTUxMGNkZiwgMHg4MWY0N2M5ZiwgMHhhZDExNjNlZCwgMHhlYTdiNTk2NSwgMHgxYTAwNzI2ZSxcbiAgICAweDExNDAzMDkyLCAweDAwZGE2ZDc3LCAweDRhMGNkZDYxLCAweGFkMWY0NjAzLCAweDYwNWJkZmIwLCAweDllZWRjMzY0LCAweDIyZWJlNmE4LCAweGNlZTdkMjhhLFxuICAgIDB4YTBlNzM2YTAsIDB4NTU2NGE2YjksIDB4MTA4NTMyMDksIDB4YzdlYjhmMzcsIDB4MmRlNzA1Y2EsIDB4ODk1MTU3MGYsIDB4ZGYwOTgyMmIsIDB4YmQ2OTFhNmMsXG4gICAgMHhhYTEyZTRmMiwgMHg4NzQ1MWMwZiwgMHhlMGY2YTI3YSwgMHgzYWRhNDgxOSwgMHg0Y2YxNzY0ZiwgMHgwZDc3MWMyYiwgMHg2N2NkYjE1NiwgMHgzNTBkODM4NCxcbiAgICAweDU5MzhmYTBmLCAweDQyMzk5ZWYzLCAweDM2OTk3YjA3LCAweDBlODQwOTNkLCAweDRhYTkzZTYxLCAweDgzNjBkODdiLCAweDFmYTk4YjBjLCAweDExNDkzODJjLFxuICAgIDB4ZTk3NjI1YTUsIDB4MDYxNGQxYjcsIDB4MGUyNTI0NGIsIDB4MGM3NjgzNDcsIDB4NTg5ZThkODIsIDB4MGQyMDU5ZDEsIDB4YTQ2NmJiMWUsIDB4ZjhkYTBhODIsXG4gICAgMHgwNGYxOTEzMCwgMHhiYTZlNGVjMCwgMHg5OTI2NTE2NCwgMHgxZWU3MjMwZCwgMHg1MGIyYWQ4MCwgMHhlYWVlNjgwMSwgMHg4ZGIyYTI4MywgMHhlYThiZjU5ZSk7XG5cbn07XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG5mdW5jdGlvbiBjYXN0NShrZXkpIHtcbiAgdGhpcy5jYXN0NSA9IG5ldyBvcGVucGdwX3N5bWVuY19jYXN0NSgpO1xuICB0aGlzLmNhc3Q1LnNldEtleSh1dGlsLnN0cjJiaW4oa2V5KSk7XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdGhpcy5jYXN0NS5lbmNyeXB0KGJsb2NrKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhc3Q1O1xubW9kdWxlLmV4cG9ydHMuYmxvY2tTaXplID0gY2FzdDUucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDg7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gY2FzdDUucHJvdG90eXBlLmtleVNpemUgPSAxNjtcbiIsIi8vUGF1bCBUZXJvLCBKdWx5IDIwMDFcbi8vaHR0cDovL3d3dy50ZXJvLmNvLnVrL2Rlcy9cbi8vXG4vL09wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMVxuLy9odHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tXG4vL1xuLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG5cbi8vVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EXG4vL0FOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuLy9JTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuLy9BUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRVxuLy9GT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuLy9EQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuLy9PUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTilcbi8vSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1Rcbi8vTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWVxuLy9PVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GXG4vL1NVQ0ggREFNQUdFLlxuXG4vL2Rlc1xuLy90aGlzIHRha2VzIHRoZSBrZXksIHRoZSBtZXNzYWdlLCBhbmQgd2hldGhlciB0byBlbmNyeXB0IG9yIGRlY3J5cHRcblxuLyoqXG4gKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvZGVzXG4gKi9cblxuXG5mdW5jdGlvbiBkZXMoa2V5cywgbWVzc2FnZSwgZW5jcnlwdCwgbW9kZSwgaXYsIHBhZGRpbmcpIHtcbiAgLy9kZWNsYXJpbmcgdGhpcyBsb2NhbGx5IHNwZWVkcyB0aGluZ3MgdXAgYSBiaXRcbiAgdmFyIHNwZnVuY3Rpb24xID0gbmV3IEFycmF5KDB4MTAxMDQwMCwgMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDEwMTAwMDQsIDB4MTA0MDQsIDB4NCwgMHgxMDAwMCwgMHg0MDAsIDB4MTAxMDQwMCxcbiAgICAweDEwMTA0MDQsIDB4NDAwLCAweDEwMDA0MDQsIDB4MTAxMDAwNCwgMHgxMDAwMDAwLCAweDQsIDB4NDA0LCAweDEwMDA0MDAsIDB4MTAwMDQwMCwgMHgxMDQwMCwgMHgxMDQwMCwgMHgxMDEwMDAwLFxuICAgIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDA0LCAweDEwMDAwMDQsIDB4MTAwMDAwNCwgMHgxMDAwNCwgMCwgMHg0MDQsIDB4MTA0MDQsIDB4MTAwMDAwMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDQsXG4gICAgMHgxMDEwMDAwLCAweDEwMTA0MDAsIDB4MTAwMDAwMCwgMHgxMDAwMDAwLCAweDQwMCwgMHgxMDEwMDA0LCAweDEwMDAwLCAweDEwNDAwLCAweDEwMDAwMDQsIDB4NDAwLCAweDQsIDB4MTAwMDQwNCxcbiAgICAweDEwNDA0LCAweDEwMTA0MDQsIDB4MTAwMDQsIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDAwMDQsIDB4NDA0LCAweDEwNDA0LCAweDEwMTA0MDAsIDB4NDA0LCAweDEwMDA0MDAsXG4gICAgMHgxMDAwNDAwLCAwLCAweDEwMDA0LCAweDEwNDAwLCAwLCAweDEwMTAwMDQpO1xuICB2YXIgc3BmdW5jdGlvbjIgPSBuZXcgQXJyYXkoLTB4N2ZlZjdmZTAsIC0weDdmZmY4MDAwLCAweDgwMDAsIDB4MTA4MDIwLCAweDEwMDAwMCwgMHgyMCwgLTB4N2ZlZmZmZTAsIC0weDdmZmY3ZmUwLCAtXG4gICAgMHg3ZmZmZmZlMCwgLTB4N2ZlZjdmZTAsIC0weDdmZWY4MDAwLCAtMHg4MDAwMDAwMCwgLTB4N2ZmZjgwMDAsIDB4MTAwMDAwLCAweDIwLCAtMHg3ZmVmZmZlMCwgMHgxMDgwMDAsIDB4MTAwMDIwLCAtXG4gICAgMHg3ZmZmN2ZlMCwgMCwgLTB4ODAwMDAwMDAsIDB4ODAwMCwgMHgxMDgwMjAsIC0weDdmZjAwMDAwLCAweDEwMDAyMCwgLTB4N2ZmZmZmZTAsIDAsIDB4MTA4MDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAtXG4gICAgMHg3ZmYwMDAwMCwgMHg4MDIwLCAwLCAweDEwODAyMCwgLTB4N2ZlZmZmZTAsIDB4MTAwMDAwLCAtMHg3ZmZmN2ZlMCwgLTB4N2ZmMDAwMDAsIC0weDdmZWY4MDAwLCAweDgwMDAsIC0weDdmZjAwMDAwLCAtXG4gICAgMHg3ZmZmODAwMCwgMHgyMCwgLTB4N2ZlZjdmZTAsIDB4MTA4MDIwLCAweDIwLCAweDgwMDAsIC0weDgwMDAwMDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAweDEwMDAwMCwgLTB4N2ZmZmZmZTAsXG4gICAgMHgxMDAwMjAsIC0weDdmZmY3ZmUwLCAtMHg3ZmZmZmZlMCwgMHgxMDAwMjAsIDB4MTA4MDAwLCAwLCAtMHg3ZmZmODAwMCwgMHg4MDIwLCAtMHg4MDAwMDAwMCwgLTB4N2ZlZmZmZTAsIC1cbiAgICAweDdmZWY3ZmUwLCAweDEwODAwMCk7XG4gIHZhciBzcGZ1bmN0aW9uMyA9IG5ldyBBcnJheSgweDIwOCwgMHg4MDIwMjAwLCAwLCAweDgwMjAwMDgsIDB4ODAwMDIwMCwgMCwgMHgyMDIwOCwgMHg4MDAwMjAwLCAweDIwMDA4LCAweDgwMDAwMDgsXG4gICAgMHg4MDAwMDA4LCAweDIwMDAwLCAweDgwMjAyMDgsIDB4MjAwMDgsIDB4ODAyMDAwMCwgMHgyMDgsIDB4ODAwMDAwMCwgMHg4LCAweDgwMjAyMDAsIDB4MjAwLCAweDIwMjAwLCAweDgwMjAwMDAsXG4gICAgMHg4MDIwMDA4LCAweDIwMjA4LCAweDgwMDAyMDgsIDB4MjAyMDAsIDB4MjAwMDAsIDB4ODAwMDIwOCwgMHg4LCAweDgwMjAyMDgsIDB4MjAwLCAweDgwMDAwMDAsIDB4ODAyMDIwMCwgMHg4MDAwMDAwLFxuICAgIDB4MjAwMDgsIDB4MjA4LCAweDIwMDAwLCAweDgwMjAyMDAsIDB4ODAwMDIwMCwgMCwgMHgyMDAsIDB4MjAwMDgsIDB4ODAyMDIwOCwgMHg4MDAwMjAwLCAweDgwMDAwMDgsIDB4MjAwLCAwLFxuICAgIDB4ODAyMDAwOCwgMHg4MDAwMjA4LCAweDIwMDAwLCAweDgwMDAwMDAsIDB4ODAyMDIwOCwgMHg4LCAweDIwMjA4LCAweDIwMjAwLCAweDgwMDAwMDgsIDB4ODAyMDAwMCwgMHg4MDAwMjA4LCAweDIwOCxcbiAgICAweDgwMjAwMDAsIDB4MjAyMDgsIDB4OCwgMHg4MDIwMDA4LCAweDIwMjAwKTtcbiAgdmFyIHNwZnVuY3Rpb240ID0gbmV3IEFycmF5KDB4ODAyMDAxLCAweDIwODEsIDB4MjA4MSwgMHg4MCwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDgwMDAwMSwgMHgyMDAxLCAwLCAweDgwMjAwMCxcbiAgICAweDgwMjAwMCwgMHg4MDIwODEsIDB4ODEsIDAsIDB4ODAwMDgwLCAweDgwMDAwMSwgMHgxLCAweDIwMDAsIDB4ODAwMDAwLCAweDgwMjAwMSwgMHg4MCwgMHg4MDAwMDAsIDB4MjAwMSwgMHgyMDgwLFxuICAgIDB4ODAwMDgxLCAweDEsIDB4MjA4MCwgMHg4MDAwODAsIDB4MjAwMCwgMHg4MDIwODAsIDB4ODAyMDgxLCAweDgxLCAweDgwMDA4MCwgMHg4MDAwMDEsIDB4ODAyMDAwLCAweDgwMjA4MSwgMHg4MSwgMCxcbiAgICAwLCAweDgwMjAwMCwgMHgyMDgwLCAweDgwMDA4MCwgMHg4MDAwODEsIDB4MSwgMHg4MDIwMDEsIDB4MjA4MSwgMHgyMDgxLCAweDgwLCAweDgwMjA4MSwgMHg4MSwgMHgxLCAweDIwMDAsIDB4ODAwMDAxLFxuICAgIDB4MjAwMSwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDIwMDEsIDB4MjA4MCwgMHg4MDAwMDAsIDB4ODAyMDAxLCAweDgwLCAweDgwMDAwMCwgMHgyMDAwLCAweDgwMjA4MCk7XG4gIHZhciBzcGZ1bmN0aW9uNSA9IG5ldyBBcnJheSgweDEwMCwgMHgyMDgwMTAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsIDB4ODAwMDAsIDB4MTAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsXG4gICAgMHg0MDA4MDEwMCwgMHg4MDAwMCwgMHgyMDAwMTAwLCAweDQwMDgwMTAwLCAweDQyMDAwMTAwLCAweDQyMDgwMDAwLCAweDgwMTAwLCAweDQwMDAwMDAwLCAweDIwMDAwMDAsIDB4NDAwODAwMDAsXG4gICAgMHg0MDA4MDAwMCwgMCwgMHg0MDAwMDEwMCwgMHg0MjA4MDEwMCwgMHg0MjA4MDEwMCwgMHgyMDAwMTAwLCAweDQyMDgwMDAwLCAweDQwMDAwMTAwLCAwLCAweDQyMDAwMDAwLCAweDIwODAxMDAsXG4gICAgMHgyMDAwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDgwMDAwLCAweDQyMDAwMTAwLCAweDEwMCwgMHgyMDAwMDAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsXG4gICAgMHg0MDA4MDEwMCwgMHgyMDAwMTAwLCAweDQwMDAwMDAwLCAweDQyMDgwMDAwLCAweDIwODAxMDAsIDB4NDAwODAxMDAsIDB4MTAwLCAweDIwMDAwMDAsIDB4NDIwODAwMDAsIDB4NDIwODAxMDAsXG4gICAgMHg4MDEwMCwgMHg0MjAwMDAwMCwgMHg0MjA4MDEwMCwgMHgyMDgwMDAwLCAwLCAweDQwMDgwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDIwMDAxMDAsIDB4NDAwMDAxMDAsIDB4ODAwMDAsIDAsXG4gICAgMHg0MDA4MDAwMCwgMHgyMDgwMTAwLCAweDQwMDAwMTAwKTtcbiAgdmFyIHNwZnVuY3Rpb242ID0gbmV3IEFycmF5KDB4MjAwMDAwMTAsIDB4MjA0MDAwMDAsIDB4NDAwMCwgMHgyMDQwNDAxMCwgMHgyMDQwMDAwMCwgMHgxMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsXG4gICAgMHgyMDAwNDAwMCwgMHg0MDQwMTAsIDB4NDAwMDAwLCAweDIwMDAwMDEwLCAweDQwMDAxMCwgMHgyMDAwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDEwLCAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCxcbiAgICAweDQwMDAsIDB4NDA0MDAwLCAweDIwMDA0MDEwLCAweDEwLCAweDIwNDAwMDEwLCAweDIwNDAwMDEwLCAwLCAweDQwNDAxMCwgMHgyMDQwNDAwMCwgMHg0MDEwLCAweDQwNDAwMCwgMHgyMDQwNDAwMCxcbiAgICAweDIwMDAwMDAwLCAweDIwMDA0MDAwLCAweDEwLCAweDIwNDAwMDEwLCAweDQwNDAwMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsIDB4NDAxMCwgMHgyMDAwMDAxMCwgMHg0MDAwMDAsIDB4MjAwMDQwMDAsXG4gICAgMHgyMDAwMDAwMCwgMHg0MDEwLCAweDIwMDAwMDEwLCAweDIwNDA0MDEwLCAweDQwNDAwMCwgMHgyMDQwMDAwMCwgMHg0MDQwMTAsIDB4MjA0MDQwMDAsIDAsIDB4MjA0MDAwMTAsIDB4MTAsIDB4NDAwMCxcbiAgICAweDIwNDAwMDAwLCAweDQwNDAxMCwgMHg0MDAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCwgMCwgMHgyMDQwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDAwMTAsIDB4MjAwMDQwMTApO1xuICB2YXIgc3BmdW5jdGlvbjcgPSBuZXcgQXJyYXkoMHgyMDAwMDAsIDB4NDIwMDAwMiwgMHg0MDAwODAyLCAwLCAweDgwMCwgMHg0MDAwODAyLCAweDIwMDgwMiwgMHg0MjAwODAwLCAweDQyMDA4MDIsXG4gICAgMHgyMDAwMDAsIDAsIDB4NDAwMDAwMiwgMHgyLCAweDQwMDAwMDAsIDB4NDIwMDAwMiwgMHg4MDIsIDB4NDAwMDgwMCwgMHgyMDA4MDIsIDB4MjAwMDAyLCAweDQwMDA4MDAsIDB4NDAwMDAwMixcbiAgICAweDQyMDAwMDAsIDB4NDIwMDgwMCwgMHgyMDAwMDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4ODAyLCAweDQyMDA4MDIsIDB4MjAwODAwLCAweDIsIDB4NDAwMDAwMCwgMHgyMDA4MDAsIDB4NDAwMDAwMCxcbiAgICAweDIwMDgwMCwgMHgyMDAwMDAsIDB4NDAwMDgwMiwgMHg0MDAwODAyLCAweDQyMDAwMDIsIDB4NDIwMDAwMiwgMHgyLCAweDIwMDAwMiwgMHg0MDAwMDAwLCAweDQwMDA4MDAsIDB4MjAwMDAwLFxuICAgIDB4NDIwMDgwMCwgMHg4MDIsIDB4MjAwODAyLCAweDQyMDA4MDAsIDB4ODAyLCAweDQwMDAwMDIsIDB4NDIwMDgwMiwgMHg0MjAwMDAwLCAweDIwMDgwMCwgMCwgMHgyLCAweDQyMDA4MDIsIDAsXG4gICAgMHgyMDA4MDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4NDAwMDAwMiwgMHg0MDAwODAwLCAweDgwMCwgMHgyMDAwMDIpO1xuICB2YXIgc3BmdW5jdGlvbjggPSBuZXcgQXJyYXkoMHgxMDAwMTA0MCwgMHgxMDAwLCAweDQwMDAwLCAweDEwMDQxMDQwLCAweDEwMDAwMDAwLCAweDEwMDAxMDQwLCAweDQwLCAweDEwMDAwMDAwLFxuICAgIDB4NDAwNDAsIDB4MTAwNDAwMDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4MTAwNDEwMDAsIDB4NDEwNDAsIDB4MTAwMCwgMHg0MCwgMHgxMDA0MDAwMCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCxcbiAgICAweDEwNDAsIDB4NDEwMDAsIDB4NDAwNDAsIDB4MTAwNDAwNDAsIDB4MTAwNDEwMDAsIDB4MTA0MCwgMCwgMCwgMHgxMDA0MDA0MCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCwgMHg0MTA0MCxcbiAgICAweDQwMDAwLCAweDQxMDQwLCAweDQwMDAwLCAweDEwMDQxMDAwLCAweDEwMDAsIDB4NDAsIDB4MTAwNDAwNDAsIDB4MTAwMCwgMHg0MTA0MCwgMHgxMDAwMTAwMCwgMHg0MCwgMHgxMDAwMDA0MCxcbiAgICAweDEwMDQwMDAwLCAweDEwMDQwMDQwLCAweDEwMDAwMDAwLCAweDQwMDAwLCAweDEwMDAxMDQwLCAwLCAweDEwMDQxMDQwLCAweDQwMDQwLCAweDEwMDAwMDQwLCAweDEwMDQwMDAwLCAweDEwMDAxMDAwLFxuICAgIDB4MTAwMDEwNDAsIDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4NDEwMDAsIDB4MTA0MCwgMHgxMDQwLCAweDQwMDQwLCAweDEwMDAwMDAwLCAweDEwMDQxMDAwKTtcblxuICAvL2NyZWF0ZSB0aGUgMTYgb3IgNDggc3Via2V5cyB3ZSB3aWxsIG5lZWRcbiAgdmFyIG0gPSAwLFxuICAgIGksIGosIHRlbXAsIHRlbXAyLCByaWdodDEsIHJpZ2h0MiwgbGVmdCwgcmlnaHQsIGxvb3Bpbmc7XG4gIHZhciBjYmNsZWZ0LCBjYmNsZWZ0MiwgY2JjcmlnaHQsIGNiY3JpZ2h0MlxuICB2YXIgZW5kbG9vcCwgbG9vcGluYztcbiAgdmFyIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xuICB2YXIgY2h1bmsgPSAwO1xuICAvL3NldCB1cCB0aGUgbG9vcHMgZm9yIHNpbmdsZSBhbmQgdHJpcGxlIGRlc1xuICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09IDMyID8gMyA6IDk7IC8vc2luZ2xlIG9yIHRyaXBsZSBkZXNcbiAgaWYgKGl0ZXJhdGlvbnMgPT0gMykge1xuICAgIGxvb3BpbmcgPSBlbmNyeXB0ID8gbmV3IEFycmF5KDAsIDMyLCAyKSA6IG5ldyBBcnJheSgzMCwgLTIsIC0yKTtcbiAgfSBlbHNlIHtcbiAgICBsb29waW5nID0gZW5jcnlwdCA/IG5ldyBBcnJheSgwLCAzMiwgMiwgNjIsIDMwLCAtMiwgNjQsIDk2LCAyKSA6IG5ldyBBcnJheSg5NCwgNjIsIC0yLCAzMiwgNjQsIDIsIDMwLCAtMiwgLTIpO1xuICB9XG5cbiAgLy9wYWQgdGhlIG1lc3NhZ2UgZGVwZW5kaW5nIG9uIHRoZSBwYWRkaW5nIHBhcmFtZXRlclxuICAvL29ubHkgYWRkIHBhZGRpbmcgaWYgZW5jcnlwdGluZyAtIG5vdGUgdGhhdCB5b3UgbmVlZCB0byB1c2UgdGhlIHNhbWUgcGFkZGluZyBvcHRpb24gZm9yIGJvdGggZW5jcnlwdCBhbmQgZGVjcnlwdFxuICBpZiAoZW5jcnlwdCkge1xuICAgIG1lc3NhZ2UgPSBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKTtcbiAgICBsZW4gPSBtZXNzYWdlLmxlbmd0aDtcbiAgfVxuXG4gIC8vc3RvcmUgdGhlIHJlc3VsdCBoZXJlXG4gIHJlc3VsdCA9IFwiXCI7XG4gIHRlbXByZXN1bHQgPSBcIlwiO1xuXG4gIGlmIChtb2RlID09IDEpIHsgLy9DQkMgbW9kZVxuICAgIGNiY2xlZnQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTtcbiAgICBjYmNyaWdodCA9IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgaXYuY2hhckNvZGVBdChtKyspO1xuICAgIG0gPSAwO1xuICB9XG5cbiAgLy9sb29wIHRocm91Z2ggZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgd2hpbGUgKG0gPCBsZW4pIHtcbiAgICBsZWZ0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBtZXNzYWdlXG4gICAgICAuY2hhckNvZGVBdChtKyspO1xuICAgIHJpZ2h0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfFxuICAgICAgbWVzc2FnZS5jaGFyQ29kZUF0KG0rKyk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGxlZnQgXj0gY2JjbGVmdDtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYmNsZWZ0MiA9IGNiY2xlZnQ7XG4gICAgICAgIGNiY3JpZ2h0MiA9IGNiY3JpZ2h0O1xuICAgICAgICBjYmNsZWZ0ID0gbGVmdDtcbiAgICAgICAgY2JjcmlnaHQgPSByaWdodDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL2ZpcnN0IGVhY2ggNjQgYnV0IGNodW5rIG9mIHRoZSBtZXNzYWdlIG11c3QgYmUgcGVybXV0ZWQgYWNjb3JkaW5nIHRvIElQXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCA0KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxNikgXiByaWdodCkgJiAweDAwMDBmZmZmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxNik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG5cbiAgICBsZWZ0ID0gKChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAzMSkpO1xuXG4gICAgLy9kbyB0aGlzIGVpdGhlciAxIG9yIDMgdGltZXMgZm9yIGVhY2ggY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgICBmb3IgKGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArPSAzKSB7XG4gICAgICBlbmRsb29wID0gbG9vcGluZ1tqICsgMV07XG4gICAgICBsb29waW5jID0gbG9vcGluZ1tqICsgMl07XG4gICAgICAvL25vdyBnbyB0aHJvdWdoIGFuZCBwZXJmb3JtIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gIFxuICAgICAgZm9yIChpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsgLy9mb3IgZWZmaWNpZW5jeVxuICAgICAgICByaWdodDEgPSByaWdodCBeIGtleXNbaV07XG4gICAgICAgIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTtcbiAgICAgICAgLy90aGUgcmVzdWx0IGlzIGF0dGFpbmVkIGJ5IHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zXG4gICAgICAgIHRlbXAgPSBsZWZ0O1xuICAgICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICAgIHJpZ2h0ID0gdGVtcCBeIChzcGZ1bmN0aW9uMlsocmlnaHQxID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjZbKHJpZ2h0MSA+Pj5cbiAgICAgICAgICA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfCBzcGZ1bmN0aW9uMVsocmlnaHQyID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb24zWyhyaWdodDIgPj4+IDE2KSAmXG4gICAgICAgICAgMHgzZl0gfCBzcGZ1bmN0aW9uNVsocmlnaHQyID4+PiA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjdbcmlnaHQyICYgMHgzZl0pO1xuICAgICAgfVxuICAgICAgdGVtcCA9IGxlZnQ7XG4gICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICByaWdodCA9IHRlbXA7IC8vdW5yZXZlcnNlIGxlZnQgYW5kIHJpZ2h0XG4gICAgfSAvL2ZvciBlaXRoZXIgMSBvciAzIGl0ZXJhdGlvbnNcblxuICAgIC8vbW92ZSB0aGVuIGVhY2ggb25lIGJpdCB0byB0aGUgcmlnaHRcbiAgICBsZWZ0ID0gKChsZWZ0ID4+PiAxKSB8IChsZWZ0IDw8IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0ID4+PiAxKSB8IChyaWdodCA8PCAzMSkpO1xuXG4gICAgLy9ub3cgcGVyZm9ybSBJUC0xLCB3aGljaCBpcyBJUCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMztcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGNiY2xlZnQgPSBsZWZ0O1xuICAgICAgICBjYmNyaWdodCA9IHJpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGVmdCBePSBjYmNsZWZ0MjtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQyO1xuICAgICAgfVxuICAgIH1cbiAgICB0ZW1wcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlZnQgPj4+IDI0KSwgKChsZWZ0ID4+PiAxNikgJiAweGZmKSwgKChsZWZ0ID4+PiA4KSAmIDB4ZmYpLCAobGVmdCAmIDB4ZmYpLCAoXG4gICAgICByaWdodCA+Pj4gMjQpLCAoKHJpZ2h0ID4+PiAxNikgJiAweGZmKSwgKChyaWdodCA+Pj4gOCkgJiAweGZmKSwgKHJpZ2h0ICYgMHhmZikpO1xuXG4gICAgY2h1bmsgKz0gODtcbiAgICBpZiAoY2h1bmsgPT0gNTEyKSB7XG4gICAgICByZXN1bHQgKz0gdGVtcHJlc3VsdDtcbiAgICAgIHRlbXByZXN1bHQgPSBcIlwiO1xuICAgICAgY2h1bmsgPSAwO1xuICAgIH1cbiAgfSAvL2ZvciBldmVyeSA4IGNoYXJhY3RlcnMsIG9yIDY0IGJpdHMgaW4gdGhlIG1lc3NhZ2VcblxuICAvL3JldHVybiB0aGUgcmVzdWx0IGFzIGFuIGFycmF5XG4gIHJlc3VsdCArPSB0ZW1wcmVzdWx0O1xuXG4gIC8vb25seSByZW1vdmUgcGFkZGluZyBpZiBkZWNyeXB0aW5nIC0gbm90ZSB0aGF0IHlvdSBuZWVkIHRvIHVzZSB0aGUgc2FtZSBwYWRkaW5nIG9wdGlvbiBmb3IgYm90aCBlbmNyeXB0IGFuZCBkZWNyeXB0XG4gIGlmICghZW5jcnlwdCkge1xuICAgIHJlc3VsdCA9IGRlc19yZW1vdmVQYWRkaW5nKHJlc3VsdCwgcGFkZGluZyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSAvL2VuZCBvZiBkZXNcblxuXG5cbi8vZGVzX2NyZWF0ZUtleXNcbi8vdGhpcyB0YWtlcyBhcyBpbnB1dCBhIDY0IGJpdCBrZXkgKGV2ZW4gdGhvdWdoIG9ubHkgNTYgYml0cyBhcmUgdXNlZClcbi8vYXMgYW4gYXJyYXkgb2YgMiBpbnRlZ2VycywgYW5kIHJldHVybnMgMTYgNDggYml0IGtleXNcblxuZnVuY3Rpb24gZGVzX2NyZWF0ZUtleXMoa2V5KSB7XG4gIC8vZGVjbGFyaW5nIHRoaXMgbG9jYWxseSBzcGVlZHMgdGhpbmdzIHVwIGEgYml0XG4gIHBjMmJ5dGVzMCA9IG5ldyBBcnJheSgwLCAweDQsIDB4MjAwMDAwMDAsIDB4MjAwMDAwMDQsIDB4MTAwMDAsIDB4MTAwMDQsIDB4MjAwMTAwMDAsIDB4MjAwMTAwMDQsIDB4MjAwLCAweDIwNCxcbiAgICAweDIwMDAwMjAwLCAweDIwMDAwMjA0LCAweDEwMjAwLCAweDEwMjA0LCAweDIwMDEwMjAwLCAweDIwMDEwMjA0KTtcbiAgcGMyYnl0ZXMxID0gbmV3IEFycmF5KDAsIDB4MSwgMHgxMDAwMDAsIDB4MTAwMDAxLCAweDQwMDAwMDAsIDB4NDAwMDAwMSwgMHg0MTAwMDAwLCAweDQxMDAwMDEsIDB4MTAwLCAweDEwMSwgMHgxMDAxMDAsXG4gICAgMHgxMDAxMDEsIDB4NDAwMDEwMCwgMHg0MDAwMTAxLCAweDQxMDAxMDAsIDB4NDEwMDEwMSk7XG4gIHBjMmJ5dGVzMiA9IG5ldyBBcnJheSgwLCAweDgsIDB4ODAwLCAweDgwOCwgMHgxMDAwMDAwLCAweDEwMDAwMDgsIDB4MTAwMDgwMCwgMHgxMDAwODA4LCAwLCAweDgsIDB4ODAwLCAweDgwOCxcbiAgICAweDEwMDAwMDAsIDB4MTAwMDAwOCwgMHgxMDAwODAwLCAweDEwMDA4MDgpO1xuICBwYzJieXRlczMgPSBuZXcgQXJyYXkoMCwgMHgyMDAwMDAsIDB4ODAwMDAwMCwgMHg4MjAwMDAwLCAweDIwMDAsIDB4MjAyMDAwLCAweDgwMDIwMDAsIDB4ODIwMjAwMCwgMHgyMDAwMCwgMHgyMjAwMDAsXG4gICAgMHg4MDIwMDAwLCAweDgyMjAwMDAsIDB4MjIwMDAsIDB4MjIyMDAwLCAweDgwMjIwMDAsIDB4ODIyMjAwMCk7XG4gIHBjMmJ5dGVzNCA9IG5ldyBBcnJheSgwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAweDEwMDAsIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCwgMHgxMDAwLFxuICAgIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCk7XG4gIHBjMmJ5dGVzNSA9IG5ldyBBcnJheSgwLCAweDQwMCwgMHgyMCwgMHg0MjAsIDAsIDB4NDAwLCAweDIwLCAweDQyMCwgMHgyMDAwMDAwLCAweDIwMDA0MDAsIDB4MjAwMDAyMCwgMHgyMDAwNDIwLFxuICAgIDB4MjAwMDAwMCwgMHgyMDAwNDAwLCAweDIwMDAwMjAsIDB4MjAwMDQyMCk7XG4gIHBjMmJ5dGVzNiA9IG5ldyBBcnJheSgwLCAweDEwMDAwMDAwLCAweDgwMDAwLCAweDEwMDgwMDAwLCAweDIsIDB4MTAwMDAwMDIsIDB4ODAwMDIsIDB4MTAwODAwMDIsIDAsIDB4MTAwMDAwMDAsXG4gICAgMHg4MDAwMCwgMHgxMDA4MDAwMCwgMHgyLCAweDEwMDAwMDAyLCAweDgwMDAyLCAweDEwMDgwMDAyKTtcbiAgcGMyYnl0ZXM3ID0gbmV3IEFycmF5KDAsIDB4MTAwMDAsIDB4ODAwLCAweDEwODAwLCAweDIwMDAwMDAwLCAweDIwMDEwMDAwLCAweDIwMDAwODAwLCAweDIwMDEwODAwLCAweDIwMDAwLCAweDMwMDAwLFxuICAgIDB4MjA4MDAsIDB4MzA4MDAsIDB4MjAwMjAwMDAsIDB4MjAwMzAwMDAsIDB4MjAwMjA4MDAsIDB4MjAwMzA4MDApO1xuICBwYzJieXRlczggPSBuZXcgQXJyYXkoMCwgMHg0MDAwMCwgMCwgMHg0MDAwMCwgMHgyLCAweDQwMDAyLCAweDIsIDB4NDAwMDIsIDB4MjAwMDAwMCwgMHgyMDQwMDAwLCAweDIwMDAwMDAsIDB4MjA0MDAwMCxcbiAgICAweDIwMDAwMDIsIDB4MjA0MDAwMiwgMHgyMDAwMDAyLCAweDIwNDAwMDIpO1xuICBwYzJieXRlczkgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMDAwMCwgMHg4LCAweDEwMDAwMDA4LCAwLCAweDEwMDAwMDAwLCAweDgsIDB4MTAwMDAwMDgsIDB4NDAwLCAweDEwMDAwNDAwLCAweDQwOCxcbiAgICAweDEwMDAwNDA4LCAweDQwMCwgMHgxMDAwMDQwMCwgMHg0MDgsIDB4MTAwMDA0MDgpO1xuICBwYzJieXRlczEwID0gbmV3IEFycmF5KDAsIDB4MjAsIDAsIDB4MjAsIDB4MTAwMDAwLCAweDEwMDAyMCwgMHgxMDAwMDAsIDB4MTAwMDIwLCAweDIwMDAsIDB4MjAyMCwgMHgyMDAwLCAweDIwMjAsXG4gICAgMHgxMDIwMDAsIDB4MTAyMDIwLCAweDEwMjAwMCwgMHgxMDIwMjApO1xuICBwYzJieXRlczExID0gbmV3IEFycmF5KDAsIDB4MTAwMDAwMCwgMHgyMDAsIDB4MTAwMDIwMCwgMHgyMDAwMDAsIDB4MTIwMDAwMCwgMHgyMDAyMDAsIDB4MTIwMDIwMCwgMHg0MDAwMDAwLCAweDUwMDAwMDAsXG4gICAgMHg0MDAwMjAwLCAweDUwMDAyMDAsIDB4NDIwMDAwMCwgMHg1MjAwMDAwLCAweDQyMDAyMDAsIDB4NTIwMDIwMCk7XG4gIHBjMmJ5dGVzMTIgPSBuZXcgQXJyYXkoMCwgMHgxMDAwLCAweDgwMDAwMDAsIDB4ODAwMTAwMCwgMHg4MDAwMCwgMHg4MTAwMCwgMHg4MDgwMDAwLCAweDgwODEwMDAsIDB4MTAsIDB4MTAxMCxcbiAgICAweDgwMDAwMTAsIDB4ODAwMTAxMCwgMHg4MDAxMCwgMHg4MTAxMCwgMHg4MDgwMDEwLCAweDgwODEwMTApO1xuICBwYzJieXRlczEzID0gbmV3IEFycmF5KDAsIDB4NCwgMHgxMDAsIDB4MTA0LCAwLCAweDQsIDB4MTAwLCAweDEwNCwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSk7XG5cbiAgLy9ob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpXG4gIHZhciBpdGVyYXRpb25zID0ga2V5Lmxlbmd0aCA+IDggPyAzIDogMTsgLy9jaGFuZ2VkIGJ5IFBhdWwgMTYvNi8yMDA3IHRvIHVzZSBUcmlwbGUgREVTIGZvciA5KyBieXRlIGtleXNcbiAgLy9zdG9yZXMgdGhlIHJldHVybiBrZXlzXG4gIHZhciBrZXlzID0gbmV3IEFycmF5KDMyICogaXRlcmF0aW9ucyk7XG4gIC8vbm93IGRlZmluZSB0aGUgbGVmdCBzaGlmdHMgd2hpY2ggbmVlZCB0byBiZSBkb25lXG4gIHZhciBzaGlmdHMgPSBuZXcgQXJyYXkoMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCk7XG4gIC8vb3RoZXIgdmFyaWFibGVzXG4gIHZhciBsZWZ0dGVtcCwgcmlnaHR0ZW1wLCBtID0gMCxcbiAgICBuID0gMCxcbiAgICB0ZW1wO1xuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaisrKSB7IC8vZWl0aGVyIDEgb3IgMyBpdGVyYXRpb25zXG4gICAgbGVmdCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcbiAgICByaWdodCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcblxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IC0xNik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMikgXiByaWdodCkgJiAweDMzMzMzMzMzO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gLTE2KSBeIGxlZnQpICYgMHgwMDAwZmZmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcblxuICAgIC8vdGhlIHJpZ2h0IHNpZGUgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgdG8gZ2V0IHRoZSBsYXN0IGZvdXIgYml0cyBvZiB0aGUgbGVmdCBzaWRlXG4gICAgdGVtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7XG4gICAgLy9sZWZ0IG5lZWRzIHRvIGJlIHB1dCB1cHNpZGUgZG93blxuICAgIGxlZnQgPSAocmlnaHQgPDwgMjQpIHwgKChyaWdodCA8PCA4KSAmIDB4ZmYwMDAwKSB8ICgocmlnaHQgPj4+IDgpICYgMHhmZjAwKSB8ICgocmlnaHQgPj4+IDI0KSAmIDB4ZjApO1xuICAgIHJpZ2h0ID0gdGVtcDtcblxuICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlc2Ugc2hpZnRzIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBrZXlzXG4gICAgZm9yIChpID0gMDsgaSA8IHNoaWZ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0XG4gICAgICBpZiAoc2hpZnRzW2ldKSB7XG4gICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7XG4gICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDIpIHwgKHJpZ2h0ID4+PiAyNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpO1xuICAgICAgICByaWdodCA9IChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMjcpO1xuICAgICAgfVxuICAgICAgbGVmdCAmPSAtMHhmO1xuICAgICAgcmlnaHQgJj0gLTB4ZjtcblxuICAgICAgLy9ub3cgYXBwbHkgUEMtMiwgaW4gc3VjaCBhIHdheSB0aGF0IEUgaXMgZWFzaWVyIHdoZW4gZW5jcnlwdGluZyBvciBkZWNyeXB0aW5nXG4gICAgICAvL3RoaXMgY29udmVyc2lvbiB3aWxsIGxvb2sgbGlrZSBQQy0yIGV4Y2VwdCBvbmx5IHRoZSBsYXN0IDYgYml0cyBvZiBlYWNoIGJ5dGUgYXJlIHVzZWRcbiAgICAgIC8vcmF0aGVyIHRoYW4gNDggY29uc2VjdXRpdmUgYml0cyBhbmQgdGhlIG9yZGVyIG9mIGxpbmVzIHdpbGwgYmUgYWNjb3JkaW5nIHRvIFxuICAgICAgLy9ob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTN1xuICAgICAgbGVmdHRlbXAgPSBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwgcGMyYnl0ZXMyWyhsZWZ0ID4+PiAyMCkgJiAweGZdIHwgcGMyYnl0ZXMzWyhcbiAgICAgICAgbGVmdCA+Pj4gMTYpICYgMHhmXSB8IHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwgcGMyYnl0ZXM2WyhsZWZ0ID4+PiA0KSAmXG4gICAgICAgIDB4Zl07XG4gICAgICByaWdodHRlbXAgPSBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfCBwYzJieXRlczlbKHJpZ2h0ID4+PiAyMCkgJiAweGZdIHxcbiAgICAgICAgcGMyYnl0ZXMxMFsocmlnaHQgPj4+IDE2KSAmIDB4Zl0gfCBwYzJieXRlczExWyhyaWdodCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzMTJbKHJpZ2h0ID4+PiA4KSAmIDB4Zl0gfFxuICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdO1xuICAgICAgdGVtcCA9ICgocmlnaHR0ZW1wID4+PiAxNikgXiBsZWZ0dGVtcCkgJiAweDAwMDBmZmZmO1xuICAgICAga2V5c1tuKytdID0gbGVmdHRlbXAgXiB0ZW1wO1xuICAgICAga2V5c1tuKytdID0gcmlnaHR0ZW1wIF4gKHRlbXAgPDwgMTYpO1xuICAgIH1cbiAgfSAvL2ZvciBlYWNoIGl0ZXJhdGlvbnNcbiAgLy9yZXR1cm4gdGhlIGtleXMgd2UndmUgY3JlYXRlZFxuICByZXR1cm4ga2V5cztcbn0gLy9lbmQgb2YgZGVzX2NyZWF0ZUtleXNcblxuXG5mdW5jdGlvbiBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKSB7XG4gIHZhciBwYWRMZW5ndGggPSA4IC0gKG1lc3NhZ2UubGVuZ3RoICUgOCk7XG4gIGlmICgocGFkZGluZyA9PSAyKSAmJiAocGFkTGVuZ3RoIDwgOCkpIHsgLy9wYWQgdGhlIG1lc3NhZ2Ugd2l0aCBzcGFjZXNcbiAgICBtZXNzYWdlICs9IFwiICAgICAgICBcIi5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09IDEpIHsgLy9QS0NTNyBwYWRkaW5nXG4gICAgbWVzc2FnZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCxcbiAgICAgIHBhZExlbmd0aCkuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH0gZWxzZSBpZiAoIXBhZGRpbmcgJiYgKHBhZExlbmd0aCA8IDgpKSB7IC8vcGFkIHRoZSBtZXNzYWdlIG91dCB3aXRoIG51bGwgYnl0ZXNcbiAgICBtZXNzYWdlICs9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIGRlc19yZW1vdmVQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpIHtcbiAgaWYgKHBhZGRpbmcgPT0gMikgeyAvLyBzcGFjZSBwYWRkZWRcbiAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKC8gKiQvZywgXCJcIik7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7IC8vIFBLQ1M3XG4gICAgdmFyIHBhZENvdW50ID0gbWVzc2FnZS5jaGFyQ29kZUF0KG1lc3NhZ2UubGVuZ3RoIC0gMSk7XG4gICAgbWVzc2FnZSA9IG1lc3NhZ2Uuc3Vic3RyKDAsIG1lc3NhZ2UubGVuZ3RoIC0gcGFkQ291bnQpO1xuICB9IGVsc2UgaWYgKCFwYWRkaW5nKSB7IC8vIG51bGwgcGFkZGluZ1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoL1xcMCokL2csIFwiXCIpO1xuICB9XG4gIHJldHVybiBtZXNzYWdlO1xufVxuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIERlcyhrZXkpIHtcbiAgdGhpcy5rZXkgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIHRoaXMua2V5LnB1c2goa2V5LnN1YnN0cihpICogOCwgOCkpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVsyXSksXG4gICAgICBkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMV0pLFxuICAgICAgZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzBdKSxcbiAgICAgIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIG51bGwpLFxuICAgICAgZmFsc2UsIDAsIG51bGwsIG51bGwpLCB0cnVlLCAwLCBudWxsLCBudWxsKSk7XG4gIH1cbn1cblxuRGVzLmtleVNpemUgPSBEZXMucHJvdG90eXBlLmtleVNpemUgPSAyNDtcbkRlcy5ibG9ja1NpemUgPSBEZXMucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDg7XG5cbi8vIFRoaXMgaXMgXCJvcmlnaW5hbFwiIERFUyAtIERlcyBpcyBhY3R1YWxseSBUcmlwbGUgREVTLlxuLy8gVGhpcyBpcyBvbmx5IGV4cG9ydGVkIHNvIHdlIGNhbiB1bml0IHRlc3QuXG5cbmZ1bmN0aW9uIE9yaWdpbmFsRGVzKGtleSkge1xuICB0aGlzLmtleSA9IGtleTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaywgcGFkZGluZykge1xuICAgIHZhciBrZXlzID0gZGVzX2NyZWF0ZUtleXModGhpcy5rZXkpO1xuICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGtleXMsIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxuXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGJsb2NrLCBwYWRkaW5nKSB7XG4gICAgdmFyIGtleXMgPSBkZXNfY3JlYXRlS2V5cyh0aGlzLmtleSk7XG4gICAgcmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoa2V5cywgdXRpbC5iaW4yc3RyKGJsb2NrKSwgZmFsc2UsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqIEBzdGF0aWMgKi9cbiAgZGVzOiBEZXMsXG4gIC8qKiBAc3RhdGljICovXG4gIG9yaWdpbmFsRGVzOiBPcmlnaW5hbERlc1xufVxuIiwiLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2NpcGhlci9hZXNcbiAqIEByZXF1aXJlcyBjcnlwdG8vY2lwaGVyL2Jsb3dmaXNoXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2NpcGhlci9jYXN0NVxuICogQHJlcXVpcmVzIGNyeXB0by9jaXBoZXIvdHdvZmlzaFxuICogQG1vZHVsZSBjcnlwdG8vY2lwaGVyXG4gKi9cblxudmFyIGRlc01vZHVsZSA9IHJlcXVpcmUoJy4vZGVzLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL2NpcGhlci9kZXMuZGVzICovXG4gIGRlczogZGVzTW9kdWxlWydkZXMnXSxcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9jaXBoZXIvZGVzLm9yaWdpbmFsRGVzICovXG4gIG9yaWdpbmFsRGVzOiBkZXNNb2R1bGVbJ29yaWdpbmFsRGVzJ10sXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vY2lwaGVyL2Nhc3Q1ICovXG4gIGNhc3Q1OiByZXF1aXJlKCcuL2Nhc3Q1LmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vY2lwaGVyL3R3b2Zpc2ggKi9cbiAgdHdvZmlzaDogcmVxdWlyZSgnLi90d29maXNoLmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vY2lwaGVyL2Jsb3dmaXNoICovXG4gIGJsb3dmaXNoOiByZXF1aXJlKCcuL2Jsb3dmaXNoLmpzJylcbn1cblxudmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gYWVzKSB7XG4gIG1vZHVsZS5leHBvcnRzWydhZXMnICsgaV0gPSBhZXNbaV07XG59XG4iLCIvKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggXG4gKiBcbiAqIENpcGhlci5qc1xuICogQSBibG9jay1jaXBoZXIgYWxnb3JpdGhtIGltcGxlbWVudGF0aW9uIG9uIEphdmFTY3JpcHRcbiAqIFNlZSBDaXBoZXIucmVhZG1lLnR4dCBmb3IgZnVydGhlciBpbmZvcm1hdGlvbi5cbiAqXG4gKiBDb3B5cmlnaHQoYykgMjAwOSBBdHN1c2hpIE9rYSBbIGh0dHA6Ly9va2EubnUvIF1cbiAqIFRoaXMgc2NyaXB0IGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExHUExcbiAqXG4gKiBBQ0tOT1dMRURHTUVOVFxuICpcbiAqICAgICBUaGUgbWFpbiBzdWJyb3V0aW5lcyBhcmUgd3JpdHRlbiBieSBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuLlxuICogXG4gKiAgICAgTWljaGllbCB2YW4gRXZlcmRpbmdlblxuICogICAgIGh0dHA6Ly9ob21lLnZlcnNhdGVsLm5sL01BdmFuRXZlcmRpbmdlbi9pbmRleC5odG1sXG4gKiBcbiAqICAgICBBbGwgcmlnaHRzIGZvciB0aGVzZSByb3V0aW5lcyBhcmUgcmVzZXJ2ZWQgdG8gTWljaGllbCB2YW4gRXZlcmRpbmdlbi5cbiAqXG4gKi9cblxuLyoqXG4gKiBAbW9kdWxlIGNyeXB0by9jaXBoZXIvdHdvZmlzaFxuICovXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vTWF0aFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBNQVhJTlQgPSAweEZGRkZGRkZGO1xuXG5mdW5jdGlvbiByb3RiKGIsIG4pIHtcbiAgcmV0dXJuIChiIDw8IG4gfCBiID4+PiAoOCAtIG4pKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIHJvdHcodywgbikge1xuICByZXR1cm4gKHcgPDwgbiB8IHcgPj4+ICgzMiAtIG4pKSAmIE1BWElOVDtcbn1cblxuZnVuY3Rpb24gZ2V0VyhhLCBpKSB7XG4gIHJldHVybiBhW2ldIHwgYVtpICsgMV0gPDwgOCB8IGFbaSArIDJdIDw8IDE2IHwgYVtpICsgM10gPDwgMjQ7XG59XG5cbmZ1bmN0aW9uIHNldFcoYSwgaSwgdykge1xuICBhLnNwbGljZShpLCA0LCB3ICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgKHcgPj4+IDE2KSAmIDB4RkYsICh3ID4+PiAyNCkgJiAweEZGKTtcbn1cblxuZnVuY3Rpb24gc2V0V0ludihhLCBpLCB3KSB7XG4gIGEuc3BsaWNlKGksIDQsICh3ID4+PiAyNCkgJiAweEZGLCAodyA+Pj4gMTYpICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgdyAmIDB4RkYpO1xufVxuXG5mdW5jdGlvbiBnZXRCKHgsIG4pIHtcbiAgcmV0dXJuICh4ID4+PiAobiAqIDgpKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIGdldE5yQml0cyhpKSB7XG4gIHZhciBuID0gMDtcbiAgd2hpbGUgKGkgPiAwKSB7XG4gICAgbisrO1xuICAgIGkgPj4+PSAxO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBnZXRNYXNrKG4pIHtcbiAgcmV0dXJuICgxIDw8IG4pIC0gMTtcbn1cblxuLy9hZGRlZCAyMDA4LzExLzEzIFhYWCBNVVNUIFVTRSBPTkUtV0FZIEhBU0ggRlVOQ1RJT04gRk9SIFNFQ1VSSVRZIFJFQVNPTlxuXG5mdW5jdGlvbiByYW5kQnl0ZSgpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDI1Nik7XG59XG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBUd29maXNoXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNyZWF0ZVR3b2Zpc2goKSB7XG4gIC8vXG4gIHZhciBrZXlCeXRlcyA9IG51bGw7XG4gIHZhciBkYXRhQnl0ZXMgPSBudWxsO1xuICB2YXIgZGF0YU9mZnNldCA9IC0xO1xuICAvLyB2YXIgZGF0YUxlbmd0aCA9IC0xO1xuICB2YXIgYWxnb3JpdGhtTmFtZSA9IG51bGw7XG4gIC8vIHZhciBpZHgyID0gLTE7XG4gIC8vXG5cbiAgYWxnb3JpdGhtTmFtZSA9IFwidHdvZmlzaFwiO1xuXG4gIHZhciB0ZnNLZXkgPSBbXTtcbiAgdmFyIHRmc00gPSBbXG4gICAgW10sXG4gICAgW10sXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBmdW5jdGlvbiB0ZnNJbml0KGtleSkge1xuICAgIGtleUJ5dGVzID0ga2V5O1xuICAgIHZhciBpLCBhLCBiLCBjLCBkLCBtZUtleSA9IFtdLFxuICAgICAgbW9LZXkgPSBbXSxcbiAgICAgIGluS2V5ID0gW107XG4gICAgdmFyIGtMZW47XG4gICAgdmFyIHNLZXkgPSBbXTtcbiAgICB2YXIgZjAxLCBmNWIsIGZlZjtcblxuICAgIHZhciBxMCA9IFtcbiAgICAgIFs4LCAxLCA3LCAxMywgNiwgMTUsIDMsIDIsIDAsIDExLCA1LCA5LCAxNCwgMTIsIDEwLCA0XSxcbiAgICAgIFsyLCA4LCAxMSwgMTMsIDE1LCA3LCA2LCAxNCwgMywgMSwgOSwgNCwgMCwgMTAsIDEyLCA1XVxuICAgIF07XG4gICAgdmFyIHExID0gW1xuICAgICAgWzE0LCAxMiwgMTEsIDgsIDEsIDIsIDMsIDUsIDE1LCA0LCAxMCwgNiwgNywgMCwgOSwgMTNdLFxuICAgICAgWzEsIDE0LCAyLCAxMSwgNCwgMTIsIDMsIDcsIDYsIDEzLCAxMCwgNSwgMTUsIDksIDAsIDhdXG4gICAgXTtcbiAgICB2YXIgcTIgPSBbXG4gICAgICBbMTEsIDEwLCA1LCAxNCwgNiwgMTMsIDksIDAsIDEyLCA4LCAxNSwgMywgMiwgNCwgNywgMV0sXG4gICAgICBbNCwgMTIsIDcsIDUsIDEsIDYsIDksIDEwLCAwLCAxNCwgMTMsIDgsIDIsIDExLCAzLCAxNV1cbiAgICBdO1xuICAgIHZhciBxMyA9IFtcbiAgICAgIFsxMywgNywgMTUsIDQsIDEsIDIsIDYsIDE0LCA5LCAxMSwgMywgMCwgOCwgNSwgMTIsIDEwXSxcbiAgICAgIFsxMSwgOSwgNSwgMSwgMTIsIDMsIDEzLCAxNCwgNiwgNCwgNywgMTUsIDIsIDAsIDgsIDEwXVxuICAgIF07XG4gICAgdmFyIHJvcjQgPSBbMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNV07XG4gICAgdmFyIGFzaHggPSBbMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLCA1LCAxNCwgN107XG4gICAgdmFyIHEgPSBbXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICB2YXIgbSA9IFtcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcblxuICAgIGZ1bmN0aW9uIGZmbTViKHgpIHtcbiAgICAgIHJldHVybiB4IF4gKHggPj4gMikgXiBbMCwgOTAsIDE4MCwgMjM4XVt4ICYgM107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmZtRWYoeCkge1xuICAgICAgcmV0dXJuIHggXiAoeCA+PiAxKSBeICh4ID4+IDIpIF4gWzAsIDIzOCwgMTgwLCA5MF1beCAmIDNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1kc1JlbShwLCBxKSB7XG4gICAgICB2YXIgaSwgdCwgdTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgdCA9IHEgPj4+IDI0O1xuICAgICAgICBxID0gKChxIDw8IDgpICYgTUFYSU5UKSB8IHAgPj4+IDI0O1xuICAgICAgICBwID0gKHAgPDwgOCkgJiBNQVhJTlQ7XG4gICAgICAgIHUgPSB0IDw8IDE7XG4gICAgICAgIGlmICh0ICYgMTI4KSB7XG4gICAgICAgICAgdSBePSAzMzM7XG4gICAgICAgIH1cbiAgICAgICAgcSBePSB0IF4gKHUgPDwgMTYpO1xuICAgICAgICB1IF49IHQgPj4+IDE7XG4gICAgICAgIGlmICh0ICYgMSkge1xuICAgICAgICAgIHUgXj0gMTY2O1xuICAgICAgICB9XG4gICAgICAgIHEgXj0gdSA8PCAyNCB8IHUgPDwgODtcbiAgICAgIH1cbiAgICAgIHJldHVybiBxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHFwKG4sIHgpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkO1xuICAgICAgYSA9IHggPj4gNDtcbiAgICAgIGIgPSB4ICYgMTU7XG4gICAgICBjID0gcTBbbl1bYSBeIGJdO1xuICAgICAgZCA9IHExW25dW3JvcjRbYl0gXiBhc2h4W2FdXTtcbiAgICAgIHJldHVybiBxM1tuXVtyb3I0W2RdIF4gYXNoeFtjXV0gPDwgNCB8IHEyW25dW2MgXiBkXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoRnVuKHgsIGtleSkge1xuICAgICAgdmFyIGEgPSBnZXRCKHgsIDApLFxuICAgICAgICBiID0gZ2V0Qih4LCAxKSxcbiAgICAgICAgYyA9IGdldEIoeCwgMiksXG4gICAgICAgIGQgPSBnZXRCKHgsIDMpO1xuICAgICAgc3dpdGNoIChrTGVuKSB7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoa2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoa2V5WzNdLCAxKTtcbiAgICAgICAgICBjID0gcVswXVtjXSBeIGdldEIoa2V5WzNdLCAyKTtcbiAgICAgICAgICBkID0gcVsxXVtkXSBeIGdldEIoa2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbMl0sIDApO1xuICAgICAgICAgIGIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihrZXlbMl0sIDMpO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgYSA9IHFbMF1bcVswXVthXSBeIGdldEIoa2V5WzFdLCAwKV0gXiBnZXRCKGtleVswXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bcVsxXVtiXSBeIGdldEIoa2V5WzFdLCAxKV0gXiBnZXRCKGtleVswXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMV1bcVswXVtjXSBeIGdldEIoa2V5WzFdLCAyKV0gXiBnZXRCKGtleVswXSwgMik7XG4gICAgICAgICAgZCA9IHFbMV1bcVsxXVtkXSBeIGdldEIoa2V5WzFdLCAzKV0gXiBnZXRCKGtleVswXSwgMyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbVswXVthXSBeIG1bMV1bYl0gXiBtWzJdW2NdIF4gbVszXVtkXTtcbiAgICB9XG5cbiAgICBrZXlCeXRlcyA9IGtleUJ5dGVzLnNsaWNlKDAsIDMyKTtcbiAgICBpID0ga2V5Qnl0ZXMubGVuZ3RoO1xuICAgIHdoaWxlIChpICE9IDE2ICYmIGkgIT0gMjQgJiYgaSAhPSAzMilcbiAgICAgIGtleUJ5dGVzW2krK10gPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGtleUJ5dGVzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICBpbktleVtpID4+IDJdID0gZ2V0VyhrZXlCeXRlcywgaSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgcVswXVtpXSA9IHFwKDAsIGkpO1xuICAgICAgcVsxXVtpXSA9IHFwKDEsIGkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIGYwMSA9IHFbMV1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMF1baV0gPSBmMDEgKyAoZjViIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIG1bMl1baV0gPSBmNWIgKyAoZmVmIDw8IDgpICsgKGYwMSA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIGYwMSA9IHFbMF1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMV1baV0gPSBmZWYgKyAoZmVmIDw8IDgpICsgKGY1YiA8PCAxNikgKyAoZjAxIDw8IDI0KTtcbiAgICAgIG1bM11baV0gPSBmNWIgKyAoZjAxIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZjViIDw8IDI0KTtcbiAgICB9XG5cbiAgICBrTGVuID0gaW5LZXkubGVuZ3RoIC8gMjtcbiAgICBmb3IgKGkgPSAwOyBpIDwga0xlbjsgaSsrKSB7XG4gICAgICBhID0gaW5LZXlbaSArIGldO1xuICAgICAgbWVLZXlbaV0gPSBhO1xuICAgICAgYiA9IGluS2V5W2kgKyBpICsgMV07XG4gICAgICBtb0tleVtpXSA9IGI7XG4gICAgICBzS2V5W2tMZW4gLSBpIC0gMV0gPSBtZHNSZW0oYSwgYik7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA0MDsgaSArPSAyKSB7XG4gICAgICBhID0gMHgxMDEwMTAxICogaTtcbiAgICAgIGIgPSBhICsgMHgxMDEwMTAxO1xuICAgICAgYSA9IGhGdW4oYSwgbWVLZXkpO1xuICAgICAgYiA9IHJvdHcoaEZ1bihiLCBtb0tleSksIDgpO1xuICAgICAgdGZzS2V5W2ldID0gKGEgKyBiKSAmIE1BWElOVDtcbiAgICAgIHRmc0tleVtpICsgMV0gPSByb3R3KGEgKyAyICogYiwgOSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgYSA9IGIgPSBjID0gZCA9IGk7XG4gICAgICBzd2l0Y2ggKGtMZW4pIHtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoc0tleVszXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbM10sIDIpO1xuICAgICAgICAgIGQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzJdLCAwKTtcbiAgICAgICAgICBiID0gcVsxXVtiXSBeIGdldEIoc0tleVsyXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihzS2V5WzJdLCAzKTtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHRmc01bMF1baV0gPSBtWzBdW3FbMF1bcVswXVthXSBeIGdldEIoc0tleVsxXSwgMCldIF4gZ2V0QihzS2V5WzBdLCAwKV07XG4gICAgICAgICAgdGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV0gXiBnZXRCKHNLZXlbMF0sIDEpXTtcbiAgICAgICAgICB0ZnNNWzJdW2ldID0gbVsyXVtxWzFdW3FbMF1bY10gXiBnZXRCKHNLZXlbMV0sIDIpXSBeIGdldEIoc0tleVswXSwgMildO1xuICAgICAgICAgIHRmc01bM11baV0gPSBtWzNdW3FbMV1bcVsxXVtkXSBeIGdldEIoc0tleVsxXSwgMyldIF4gZ2V0QihzS2V5WzBdLCAzKV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzAoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMCldIF4gdGZzTVsxXVtnZXRCKHgsIDEpXSBeIHRmc01bMl1bZ2V0Qih4LCAyKV0gXiB0ZnNNWzNdW2dldEIoeCwgMyldO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzEoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMyldIF4gdGZzTVsxXVtnZXRCKHgsIDApXSBeIHRmc01bMl1bZ2V0Qih4LCAxKV0gXiB0ZnNNWzNdW2dldEIoeCwgMildO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRnJuZChyLCBibGspIHtcbiAgICB2YXIgYSA9IHRmc0cwKGJsa1swXSk7XG4gICAgdmFyIGIgPSB0ZnNHMShibGtbMV0pO1xuICAgIGJsa1syXSA9IHJvdHcoYmxrWzJdIF4gKGEgKyBiICsgdGZzS2V5WzQgKiByICsgOF0pICYgTUFYSU5ULCAzMSk7XG4gICAgYmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBibGtbMV0gPSByb3R3KGJsa1sxXSwgMSkgXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiByICsgMTFdKSAmIE1BWElOVDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0lybmQoaSwgYmxrKSB7XG4gICAgdmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuICAgIHZhciBiID0gdGZzRzEoYmxrWzFdKTtcbiAgICBibGtbMl0gPSByb3R3KGJsa1syXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMF0pICYgTUFYSU5UO1xuICAgIGJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7XG4gICAgYmxrWzFdID0gcm90dyhibGtbMV0gXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiBpICsgOV0pICYgTUFYSU5ULCAzMSk7XG4gIH1cblxuICBmdW5jdGlvbiB0ZnNDbG9zZSgpIHtcbiAgICB0ZnNLZXkgPSBbXTtcbiAgICB0ZnNNID0gW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgICAgW11cbiAgICBdO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRW5jcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbMF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbMV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbMl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzNdXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykge1xuICAgICAgdGZzRnJuZChqLCBibGspO1xuICAgIH1cbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzRdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA4LCBibGtbMF0gXiB0ZnNLZXlbNl0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVs3XSk7XG4gICAgZGF0YU9mZnNldCArPSAxNjtcbiAgICByZXR1cm4gZGF0YUJ5dGVzO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRGVjcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbNF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbNV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbNl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzddXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHRmc0lybmQoaiwgYmxrKTtcbiAgICB9XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVswXSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzJdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbM10pO1xuICAgIGRhdGFPZmZzZXQgKz0gMTY7XG4gIH1cblxuICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbiAgZnVuY3Rpb24gdGZzRmluYWwoKSB7XG4gICAgcmV0dXJuIGRhdGFCeXRlcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ0d29maXNoXCIsXG4gICAgYmxvY2tzaXplOiAxMjggLyA4LFxuICAgIG9wZW46IHRmc0luaXQsXG4gICAgY2xvc2U6IHRmc0Nsb3NlLFxuICAgIGVuY3J5cHQ6IHRmc0VuY3J5cHQsXG4gICAgZGVjcnlwdDogdGZzRGVjcnlwdCxcbiAgICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG4gICAgZmluYWxpemU6IHRmc0ZpbmFsXG4gIH07XG59XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIFRGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBibG9ja19jb3B5ID0gW10uY29uY2F0KGJsb2NrKTtcbiAgdmFyIHRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0Zi5vcGVuKHV0aWwuc3RyMmJpbihrZXkpLCAwKTtcbiAgdmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7XG4gIHRmLmNsb3NlKCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIFRGKGtleSkge1xuICB0aGlzLnRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0aGlzLnRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksIDApO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMudGYuZW5jcnlwdChbXS5jb25jYXQoYmxvY2spLCAwKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gVEY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gVEYucHJvdG90eXBlLmtleVNpemUgPSAzMjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IFRGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxuLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2NpcGhlclxuICogQHJlcXVpcmVzIGNyeXB0by9wdWJsaWNfa2V5XG4gKiBAcmVxdWlyZXMgY3J5cHRvL3JhbmRvbVxuICogQHJlcXVpcmVzIHR5cGUvbXBpXG4gKiBAbW9kdWxlIGNyeXB0by9jcnlwdG9cbiAqL1xuXG52YXIgcmFuZG9tID0gcmVxdWlyZSgnLi9yYW5kb20uanMnKSxcbiAgY2lwaGVyID0gcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBFbmNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAgICogYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHttb2R1bGU6dHlwZS9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gICAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IGlmIFJTQSBhbiBtb2R1bGU6dHlwZS9tcGk7IFxuICAgKiBpZiBlbGdhbWFsIGVuY3J5cHRpb24gYW4gYXJyYXkgb2YgdHdvIG1vZHVsZTp0eXBlL21waSBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIG51bGxcbiAgICovXG4gIHB1YmxpY0tleUVuY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIHB1YmxpY01QSXMsIGRhdGEpIHtcbiAgICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICAgICAgdmFyIG4gPSBwdWJsaWNNUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBlID0gcHVibGljTVBJc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIFtyc2EuZW5jcnlwdChtLCBlLCBuKV07XG5cbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgcCA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGcgPSBwdWJsaWNNUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciB5ID0gcHVibGljTVBJc1syXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIGVsZ2FtYWwuZW5jcnlwdChtLCBnLCBwLCB5KTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIG1waS5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgICByZXR1cm4gbXBpO1xuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHVibGljIGtleSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBvZiB0aGUgcHJpdmF0ZSBrZXksXG4gICAqIHRoZSBzcGVjaWZpZWQgc2VjcmV0TVBJcyBvZiB0aGUgcHJpdmF0ZSBrZXkgYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIG9mIHRoZSBwdWJsaWMga2V5IHBhcnQgb2YgdGhlIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7QXJyYXk8bW9kdWxlOnR5cGUvbXBpPn0gc2VjcmV0TVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgdXNlZFxuICAgKiBAcGFyYW0ge21vZHVsZTp0eXBlL21waX0gZGF0YSBEYXRhIHRvIGJlIGVuY3J5cHRlZCBhcyBNUElcbiAgICogQHJldHVybiB7bW9kdWxlOnR5cGUvbXBpfSByZXR1cm5zIGEgYmlnIGludGVnZXIgY29udGFpbmluZyB0aGUgZGVjcnlwdGVkIGRhdGE7IG90aGVyd2lzZSBudWxsXG4gICAqL1xuXG4gIHB1YmxpY0tleURlY3J5cHQ6IGZ1bmN0aW9uKGFsZ28sIGtleUludGVnZXJzLCBkYXRhSW50ZWdlcnMpIHtcbiAgICB2YXIgYm4gPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICAvLyAwIGFuZCAxIGFyZSB0aGUgcHVibGljIGtleS5cbiAgICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHEgPSBrZXlJbnRlZ2Vyc1s0XS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgdSA9IGtleUludGVnZXJzWzVdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHJldHVybiByc2EuZGVjcnlwdChtLCBkLCBwLCBxLCB1KTtcbiAgICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgICAgdmFyIGVsZ2FtYWwgPSBuZXcgcHVibGljS2V5LmVsZ2FtYWwoKTtcbiAgICAgICAgICB2YXIgeCA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBjMSA9IGRhdGFJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgYzIgPSBkYXRhSW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gZWxnYW1hbC5kZWNyeXB0KGMxLCBjMiwgcCwgeCk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSkoKTtcblxuICAgIHZhciByZXN1bHQgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICByZXN1bHQuZnJvbUJpZ0ludGVnZXIoYm4pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBpbnRlZ2VycyBjb21wcmlzaW5nIHRoZSBwcml2YXRlIGtleSBvZiBhbiBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFsZ28gVGhlIHB1YmxpYyBrZXkgYWxnb3JpdGhtXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBudW1iZXIgb2YgaW50ZWdlcnMuXG4gICAqL1xuICBnZXRQcml2YXRlTXBpQ291bnQ6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIG11bHRpcHJlY2lzaW9uIGludGVnZXIgKE1QSSkgb2YgUlNBIHNlY3JldCBleHBvbmVudCBkLlxuICAgICAgICAvLyAgIC0gTVBJIG9mIFJTQSBzZWNyZXQgcHJpbWUgdmFsdWUgcC5cbiAgICAgICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHEgKHAgPCBxKS5cbiAgICAgICAgLy8gICAtIE1QSSBvZiB1LCB0aGUgbXVsdGlwbGljYXRpdmUgaW52ZXJzZSBvZiBwLCBtb2QgcS5cbiAgICAgICAgcmV0dXJuIDQ7XG4gICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRWxnYW1hbCBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIE1QSSBvZiBFbGdhbWFsIHNlY3JldCBleHBvbmVudCB4LlxuICAgICAgICByZXR1cm4gMTtcbiAgICAgIGNhc2UgJ2RzYSc6XG4gICAgICAgIC8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBzZWNyZXQga2V5czpcbiAgICAgICAgLy8gICAtIE1QSSBvZiBEU0Egc2VjcmV0IGV4cG9uZW50IHguXG4gICAgICAgIHJldHVybiAxO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobScpO1xuICAgIH1cbiAgfSxcblxuICBnZXRQdWJsaWNNcGlDb3VudDogZnVuY3Rpb24oYWxnbykge1xuICAgIC8vIC0gQSBzZXJpZXMgb2YgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgY29tcHJpc2luZyB0aGUga2V5IG1hdGVyaWFsOlxuICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHB1YmxpYyBrZXlzOlxuICAgIC8vICAgICAgIC0gYSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBwdWJsaWMgbW9kdWx1cyBuO1xuICAgIC8vICAgICAgIC0gYW4gTVBJIG9mIFJTQSBwdWJsaWMgZW5jcnlwdGlvbiBleHBvbmVudCBlLlxuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICBjYXNlICdyc2Ffc2lnbic6XG4gICAgICAgIHJldHVybiAyO1xuXG4gICAgICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRWxnYW1hbCBwdWJsaWMga2V5czpcbiAgICAgICAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHJpbWUgcDtcbiAgICAgICAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgZ3JvdXAgZ2VuZXJhdG9yIGc7XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIHB1YmxpYyBrZXkgdmFsdWUgeSAoPSBnKip4IG1vZCBwIHdoZXJlIHggIGlzIHNlY3JldCkuXG4gICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgcmV0dXJuIDM7XG5cbiAgICAgICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0EgcHVibGljIGtleXM6XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBwcmltZSBwO1xuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgZ3JvdXAgb3JkZXIgcSAocSBpcyBhIHByaW1lIGRpdmlzb3Igb2YgcC0xKTtcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIGdlbmVyYXRvciBnO1xuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgcHVibGljLWtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS5cbiAgICAgIGNhc2UgJ2RzYSc6XG4gICAgICAgIHJldHVybiA0O1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gYWxnb3JpdGhtLicpO1xuICAgIH1cbiAgfSxcblxuICBnZW5lcmF0ZU1waTogZnVuY3Rpb24oYWxnbywgYml0cykge1xuICAgIHZhciByZXN1bHQgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICAgIC8vcmVtZW1iZXIgXCJwdWJsaWNLZXlcIiByZWZlcnMgdG8gdGhlIGNyeXB0by9wdWJsaWNfa2V5IGRpclxuICAgICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICAgIHZhciBrZXlPYmplY3QgPSByc2EuZ2VuZXJhdGUoYml0cywgXCIxMDAwMVwiKTtcbiAgICAgICAgICB2YXIgb3V0cHV0ID0gW107XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0Lm4pO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5lZSk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LmQpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5wKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QucSk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LnUpO1xuICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBhbGdvcml0aG0gZm9yIGtleSBnZW5lcmF0aW9uLicpO1xuICAgICAgfVxuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lm1hcChmdW5jdGlvbihibikge1xuICAgICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgbXBpLmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgICAgIHJldHVybiBtcGk7XG4gICAgfSk7XG4gIH0sXG5cblxuICAvKipcbiAgICogZ2VuZXJhdGUgcmFuZG9tIGJ5dGUgcHJlZml4IGFzIHN0cmluZyBmb3IgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMilcbiAgICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgd2l0aCBsZW5ndGggZXF1YWwgdG8gdGhlIGJsb2NrXG4gICAqIHNpemUgb2YgdGhlIGNpcGhlclxuICAgKi9cbiAgZ2V0UHJlZml4UmFuZG9tOiBmdW5jdGlvbihhbGdvKSB7XG4gICAgcmV0dXJuIHJhbmRvbS5nZXRSYW5kb21CeXRlcyhjaXBoZXJbYWxnb10uYmxvY2tTaXplKTtcbiAgfSxcblxuICAvKipcbiAgICogR2VuZXJhdGluZyBhIHNlc3Npb24ga2V5IGZvciB0aGUgc3BlY2lmaWVkIHN5bW1ldHJpYyBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byB1c2UgKHNlZSBSRkM0ODgwIDkuMilcbiAgICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIGtleVxuICAgKi9cbiAgZ2VuZXJhdGVTZXNzaW9uS2V5OiBmdW5jdGlvbihhbGdvKSB7XG4gICAgcmV0dXJuIHJhbmRvbS5nZXRSYW5kb21CeXRlcyhjaXBoZXJbYWxnb10ua2V5U2l6ZSk7XG4gIH1cbn07XG4iLCIvKipcbiAqIEByZXF1aXJlcyBjcnlwdG8vaGFzaC9zaGFcbiAqIEBtb2R1bGUgY3J5cHRvL2hhc2hcbiAqL1xudmFyIHNoYSA9IHJlcXVpcmUoJy4vc2hhLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL2hhc2gvbWQ1ICovXG4gIG1kNTogcmVxdWlyZSgnLi9tZDUuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9oYXNoL3NoYS5zaGExICovXG4gIHNoYTE6IHNoYS5zaGExLFxuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL2hhc2gvc2hhLnNoYTIyNCAqL1xuICBzaGEyMjQ6IHNoYS5zaGEyMjQsXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vaGFzaC9zaGEuc2hhMjU2ICovXG4gIHNoYTI1Njogc2hhLnNoYTI1NixcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9oYXNoL3NoYS5zaGEzODQgKi9cbiAgc2hhMzg0OiBzaGEuc2hhMzg0LFxuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL2hhc2gvc2hhLnNoYTUxMiAqL1xuICBzaGE1MTI6IHNoYS5zaGE1MTIsXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vaGFzaC9yaXBlLW1kICovXG4gIHJpcGVtZDogcmVxdWlyZSgnLi9yaXBlLW1kLmpzJyksXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGhhc2ggb24gdGhlIHNwZWNpZmllZCBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChzZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgaGFzaGVkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gaGFzaCB2YWx1ZVxuICAgKi9cbiAgZGlnZXN0OiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIC0gTUQ1IFtIQUNdXG4gICAgICAgIHJldHVybiB0aGlzLm1kNShkYXRhKTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gLSBTSEEtMSBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMShkYXRhKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gLSBSSVBFLU1ELzE2MCBbSEFDXVxuICAgICAgICByZXR1cm4gdGhpcy5yaXBlbWQoZGF0YSk7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIC8vIC0gU0hBMjU2IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEyNTYoZGF0YSk7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIC0gU0hBMzg0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEzODQoZGF0YSk7XG4gICAgICBjYXNlIDEwOlxuICAgICAgICAvLyAtIFNIQTUxMiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhNTEyKGRhdGEpO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gLSBTSEEyMjQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTIyNChkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoYXNoIGZ1bmN0aW9uLicpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaGFzaCBzaXplIGluIGJ5dGVzIG9mIHRoZSBzcGVjaWZpZWQgaGFzaCBhbGdvcml0aG0gdHlwZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSAoU2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBTaXplIGluIGJ5dGVzIG9mIHRoZSByZXN1bHRpbmcgaGFzaFxuICAgKi9cbiAgZ2V0SGFzaEJ5dGVMZW5ndGg6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gLSBNRDUgW0hBQ11cbiAgICAgICAgcmV0dXJuIDE2O1xuICAgICAgY2FzZSAyOlxuICAgICAgICAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyAtIFJJUEUtTUQvMTYwIFtIQUNdXG4gICAgICAgIHJldHVybiAyMDtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgLy8gLSBTSEEyNTYgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiAzMjtcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgLy8gLSBTSEEzODQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA0OFxuICAgICAgY2FzZSAxMDpcbiAgICAgICAgLy8gLSBTSEE1MTIgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA2NDtcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIC8vIC0gU0hBMjI0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gMjg7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGFzaCBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEEgZmFzdCBNRDUgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvblxuICogQ29weXJpZ2h0IChjKSAyMDEyIEpvc2VwaCBNeWVyc1xuICogaHR0cDovL3d3dy5teWVyc2RhaWx5Lm9yZy9qb3NlcGgvamF2YXNjcmlwdC9tZDUtdGV4dC5odG1sXG4gKlxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZVxuICogYW5kIGl0cyBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZXMgYW5kIHdpdGhvdXRcbiAqIGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCBwcm92aWRlZCB0aGF0IHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYXBwZWFycyBpbiBhbGwgY29waWVzLlxuICpcbiAqIE9mIGNvdXJzZSwgdGhpcyBzb2Z0IGlzIHByb3ZpZGVkIFwiYXMgaXNcIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZFxuICogd2FycmFudHkgb2YgYW55IGtpbmQuXG4gKi9cblxuLyoqXG4gKiBAcmVxdWlyZXMgdXRpbFxuICogQG1vZHVsZSBjcnlwdG8vaGFzaC9tZDVcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLyoqXG4gKiBNRDUgaGFzaFxuICogQHBhcmFtIHtTdHJpbmd9IGVudHJlZSBzdHJpbmcgdG8gaGFzaFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChlbnRyZWUpIHtcbiAgdmFyIGhleCA9IG1kNShlbnRyZWUpO1xuICB2YXIgYmluID0gdXRpbC5oZXgyYmluKGhleCk7XG4gIHJldHVybiBiaW47XG59XG5cbmZ1bmN0aW9uIG1kNWN5Y2xlKHgsIGspIHtcbiAgdmFyIGEgPSB4WzBdLFxuICAgIGIgPSB4WzFdLFxuICAgIGMgPSB4WzJdLFxuICAgIGQgPSB4WzNdO1xuXG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzBdLCA3LCAtNjgwODc2OTM2KTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbMV0sIDEyLCAtMzg5NTY0NTg2KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbMl0sIDE3LCA2MDYxMDU4MTkpO1xuICBiID0gZmYoYiwgYywgZCwgYSwga1szXSwgMjIsIC0xMDQ0NTI1MzMwKTtcbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbNF0sIDcsIC0xNzY0MTg4OTcpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1s1XSwgMTIsIDEyMDAwODA0MjYpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1s2XSwgMTcsIC0xNDczMjMxMzQxKTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbN10sIDIyLCAtNDU3MDU5ODMpO1xuICBhID0gZmYoYSwgYiwgYywgZCwga1s4XSwgNywgMTc3MDAzNTQxNik7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1sxMF0sIDE3LCAtNDIwNjMpO1xuICBiID0gZmYoYiwgYywgZCwgYSwga1sxMV0sIDIyLCAtMTk5MDQwNDE2Mik7XG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzEyXSwgNywgMTgwNDYwMzY4Mik7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzEzXSwgMTIsIC00MDM0MTEwMSk7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbMTVdLCAyMiwgMTIzNjUzNTMyOSk7XG5cbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbMV0sIDUsIC0xNjU3OTY1MTApO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1s2XSwgOSwgLTEwNjk1MDE2MzIpO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1sxMV0sIDE0LCA2NDM3MTc3MTMpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1swXSwgMjAsIC0zNzM4OTczMDIpO1xuICBhID0gZ2coYSwgYiwgYywgZCwga1s1XSwgNSwgLTcwMTU1ODY5MSk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzEwXSwgOSwgMzgwMTYwODMpO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1sxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbOV0sIDUsIDU2ODQ0NjQzOCk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzE0XSwgOSwgLTEwMTk4MDM2OTApO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1szXSwgMTQsIC0xODczNjM5NjEpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1s4XSwgMjAsIDExNjM1MzE1MDEpO1xuICBhID0gZ2coYSwgYiwgYywgZCwga1sxM10sIDUsIC0xNDQ0NjgxNDY3KTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbMl0sIDksIC01MTQwMzc4NCk7XG4gIGMgPSBnZyhjLCBkLCBhLCBiLCBrWzddLCAxNCwgMTczNTMyODQ3Myk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzEyXSwgMjAsIC0xOTI2NjA3NzM0KTtcblxuICBhID0gaGgoYSwgYiwgYywgZCwga1s1XSwgNCwgLTM3ODU1OCk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1sxMV0sIDE2LCAxODM5MDMwNTYyKTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbMTRdLCAyMywgLTM1MzA5NTU2KTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbMV0sIDQsIC0xNTMwOTkyMDYwKTtcbiAgZCA9IGhoKGQsIGEsIGIsIGMsIGtbNF0sIDExLCAxMjcyODkzMzUzKTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICBhID0gaGgoYSwgYiwgYywgZCwga1sxM10sIDQsIDY4MTI3OTE3NCk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzBdLCAxMSwgLTM1ODUzNzIyMik7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzNdLCAxNiwgLTcyMjUyMTk3OSk7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzZdLCAyMywgNzYwMjkxODkpO1xuICBhID0gaGgoYSwgYiwgYywgZCwga1s5XSwgNCwgLTY0MDM2NDQ4Nyk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzEyXSwgMTEsIC00MjE4MTU4MzUpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1sxNV0sIDE2LCA1MzA3NDI1MjApO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1syXSwgMjMsIC05OTUzMzg2NTEpO1xuXG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzBdLCA2LCAtMTk4NjMwODQ0KTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbN10sIDEwLCAxMTI2ODkxNDE1KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1s1XSwgMjEsIC01NzQzNDA1NSk7XG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzEyXSwgNiwgMTcwMDQ4NTU3MSk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1sxMF0sIDE1LCAtMTA1MTUyMyk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuICBhID0gaWkoYSwgYiwgYywgZCwga1s4XSwgNiwgMTg3MzMxMzM1OSk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzZdLCAxNSwgLTE1NjAxOTgzODApO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1sxM10sIDIxLCAxMzA5MTUxNjQ5KTtcbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbNF0sIDYsIC0xNDU1MjMwNzApO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1sxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzJdLCAxNSwgNzE4Nzg3MjU5KTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbOV0sIDIxLCAtMzQzNDg1NTUxKTtcblxuICB4WzBdID0gYWRkMzIoYSwgeFswXSk7XG4gIHhbMV0gPSBhZGQzMihiLCB4WzFdKTtcbiAgeFsyXSA9IGFkZDMyKGMsIHhbMl0pO1xuICB4WzNdID0gYWRkMzIoZCwgeFszXSk7XG5cbn1cblxuZnVuY3Rpb24gY21uKHEsIGEsIGIsIHgsIHMsIHQpIHtcbiAgYSA9IGFkZDMyKGFkZDMyKGEsIHEpLCBhZGQzMih4LCB0KSk7XG4gIHJldHVybiBhZGQzMigoYSA8PCBzKSB8IChhID4+PiAoMzIgLSBzKSksIGIpO1xufVxuXG5mdW5jdGlvbiBmZihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBjbW4oKGIgJiBjKSB8ICgofmIpICYgZCksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBnZyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBjbW4oKGIgJiBkKSB8IChjICYgKH5kKSksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBoaChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBjbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gaWkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKGMgXiAoYiB8ICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1MShzKSB7XG4gIHR4dCA9ICcnO1xuICB2YXIgbiA9IHMubGVuZ3RoLFxuICAgIHN0YXRlID0gWzE3MzI1ODQxOTMsIC0yNzE3MzM4NzksIC0xNzMyNTg0MTk0LCAyNzE3MzM4NzhdLFxuICAgIGk7XG4gIGZvciAoaSA9IDY0OyBpIDw9IHMubGVuZ3RoOyBpICs9IDY0KSB7XG4gICAgbWQ1Y3ljbGUoc3RhdGUsIG1kNWJsayhzLnN1YnN0cmluZyhpIC0gNjQsIGkpKSk7XG4gIH1cbiAgcyA9IHMuc3Vic3RyaW5nKGkgLSA2NCk7XG4gIHZhciB0YWlsID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICBmb3IgKGkgPSAwOyBpIDwgcy5sZW5ndGg7IGkrKylcbiAgICB0YWlsW2kgPj4gMl0gfD0gcy5jaGFyQ29kZUF0KGkpIDw8ICgoaSAlIDQpIDw8IDMpO1xuICB0YWlsW2kgPj4gMl0gfD0gMHg4MCA8PCAoKGkgJSA0KSA8PCAzKTtcbiAgaWYgKGkgPiA1NSkge1xuICAgIG1kNWN5Y2xlKHN0YXRlLCB0YWlsKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgdGFpbFtpXSA9IDA7XG4gIH1cbiAgdGFpbFsxNF0gPSBuICogODtcbiAgbWQ1Y3ljbGUoc3RhdGUsIHRhaWwpO1xuICByZXR1cm4gc3RhdGU7XG59XG5cbi8qIHRoZXJlIG5lZWRzIHRvIGJlIHN1cHBvcnQgZm9yIFVuaWNvZGUgaGVyZSxcbiAqIHVubGVzcyB3ZSBwcmV0ZW5kIHRoYXQgd2UgY2FuIHJlZGVmaW5lIHRoZSBNRC01XG4gKiBhbGdvcml0aG0gZm9yIG11bHRpLWJ5dGUgY2hhcmFjdGVycyAocGVyaGFwc1xuICogYnkgYWRkaW5nIGV2ZXJ5IGZvdXIgMTYtYml0IGNoYXJhY3RlcnMgYW5kXG4gKiBzaG9ydGVuaW5nIHRoZSBzdW0gdG8gMzIgYml0cykuIE90aGVyd2lzZVxuICogSSBzdWdnZXN0IHBlcmZvcm1pbmcgTUQtNSBhcyBpZiBldmVyeSBjaGFyYWN0ZXJcbiAqIHdhcyB0d28gYnl0ZXMtLWUuZy4sIDAwNDAgMDAyNSA9IEAlLS1idXQgdGhlblxuICogaG93IHdpbGwgYW4gb3JkaW5hcnkgTUQtNSBzdW0gYmUgbWF0Y2hlZD9cbiAqIFRoZXJlIGlzIG5vIHdheSB0byBzdGFuZGFyZGl6ZSB0ZXh0IHRvIHNvbWV0aGluZ1xuICogbGlrZSBVVEYtOCBiZWZvcmUgdHJhbnNmb3JtYXRpb247IHNwZWVkIGNvc3QgaXNcbiAqIHV0dGVybHkgcHJvaGliaXRpdmUuIFRoZSBKYXZhU2NyaXB0IHN0YW5kYXJkXG4gKiBpdHNlbGYgbmVlZHMgdG8gbG9vayBhdCB0aGlzOiBpdCBzaG91bGQgc3RhcnRcbiAqIHByb3ZpZGluZyBhY2Nlc3MgdG8gc3RyaW5ncyBhcyBwcmVmb3JtZWQgVVRGLThcbiAqIDgtYml0IHVuc2lnbmVkIHZhbHVlIGFycmF5cy5cbiAqL1xuZnVuY3Rpb24gbWQ1YmxrKHMpIHsgLyogSSBmaWd1cmVkIGdsb2JhbCB3YXMgZmFzdGVyLiAgICovXG4gIHZhciBtZDVibGtzID0gW10sXG4gICAgaTsgLyogQW5keSBLaW5nIHNhaWQgZG8gaXQgdGhpcyB3YXkuICovXG4gIGZvciAoaSA9IDA7IGkgPCA2NDsgaSArPSA0KSB7XG4gICAgbWQ1Ymxrc1tpID4+IDJdID0gcy5jaGFyQ29kZUF0KGkpICsgKHMuY2hhckNvZGVBdChpICsgMSkgPDwgOCkgKyAocy5jaGFyQ29kZUF0KGkgKyAyKSA8PCAxNikgKyAocy5jaGFyQ29kZUF0KGkgKyAzKSA8PFxuICAgICAgMjQpO1xuICB9XG4gIHJldHVybiBtZDVibGtzO1xufVxuXG52YXIgaGV4X2NociA9ICcwMTIzNDU2Nzg5YWJjZGVmJy5zcGxpdCgnJyk7XG5cbmZ1bmN0aW9uIHJoZXgobikge1xuICB2YXIgcyA9ICcnLFxuICAgIGogPSAwO1xuICBmb3IgKDsgaiA8IDQ7IGorKylcbiAgICBzICs9IGhleF9jaHJbKG4gPj4gKGogKiA4ICsgNCkpICYgMHgwRl0gKyBoZXhfY2hyWyhuID4+IChqICogOCkpICYgMHgwRl07XG4gIHJldHVybiBzO1xufVxuXG5mdW5jdGlvbiBoZXgoeCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpKyspXG4gICAgeFtpXSA9IHJoZXgoeFtpXSk7XG4gIHJldHVybiB4LmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBtZDUocykge1xuICByZXR1cm4gaGV4KG1kNTEocykpO1xufVxuXG4vKiB0aGlzIGZ1bmN0aW9uIGlzIG11Y2ggZmFzdGVyLFxuc28gaWYgcG9zc2libGUgd2UgdXNlIGl0LiBTb21lIElFc1xuYXJlIHRoZSBvbmx5IG9uZXMgSSBrbm93IG9mIHRoYXRcbm5lZWQgdGhlIGlkaW90aWMgc2Vjb25kIGZ1bmN0aW9uLFxuZ2VuZXJhdGVkIGJ5IGFuIGlmIGNsYXVzZS4gICovXG5cbmZ1bmN0aW9uIGFkZDMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgJiAweEZGRkZGRkZGO1xufVxuXG5pZiAobWQ1KCdoZWxsbycpICE9ICc1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MicpIHtcbiAgZnVuY3Rpb24gYWRkMzIoeCwgeSkge1xuICAgIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRiksXG4gICAgICBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgfVxufVxuIiwiLypcbiAqIENyeXB0b01YIFRvb2xzXG4gKiBDb3B5cmlnaHQgKEMpIDIwMDQgLSAyMDA2IERlcmVrIEJ1aXRlbmh1aXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDJcbiAqIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcsIFVTQS5cbiAqL1xuXG4vKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqL1xuXG4vKipcbiAqIEBtb2R1bGUgY3J5cHRvL2hhc2gvcmlwZS1tZFxuICovXG5cbnZhciBSTURzaXplID0gMTYwO1xudmFyIFggPSBuZXcgQXJyYXkoKTtcblxuZnVuY3Rpb24gUk9MKHgsIG4pIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpKTtcbn1cblxuZnVuY3Rpb24gRih4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKHggXiB5IF4geik7XG59XG5cbmZ1bmN0aW9uIEcoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCAmIHkpIHwgKH54ICYgeikpO1xufVxuXG5mdW5jdGlvbiBIKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggfCB+eSkgXiB6KTtcbn1cblxuZnVuY3Rpb24gSSh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4ICYgeikgfCAoeSAmIH56KSk7XG59XG5cbmZ1bmN0aW9uIEooeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcih4IF4gKHkgfCB+eikpO1xufVxuXG5mdW5jdGlvbiBtaXhPbmVSb3VuZChhLCBiLCBjLCBkLCBlLCB4LCBzLCByb3VuZE51bWJlcikge1xuICBzd2l0Y2ggKHJvdW5kTnVtYmVyKSB7XG4gICAgY2FzZSAwOlxuICAgICAgYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBhICs9IEcoYiwgYywgZCkgKyB4ICsgMHg1YTgyNzk5OTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGEgKz0gSChiLCBjLCBkKSArIHggKyAweDZlZDllYmExO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAzOlxuICAgICAgYSArPSBJKGIsIGMsIGQpICsgeCArIDB4OGYxYmJjZGM7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDQ6XG4gICAgICBhICs9IEooYiwgYywgZCkgKyB4ICsgMHhhOTUzZmQ0ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNTpcbiAgICAgIGEgKz0gSihiLCBjLCBkKSArIHggKyAweDUwYTI4YmU2O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA2OlxuICAgICAgYSArPSBJKGIsIGMsIGQpICsgeCArIDB4NWM0ZGQxMjQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDc6XG4gICAgICBhICs9IEgoYiwgYywgZCkgKyB4ICsgMHg2ZDcwM2VmMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgODpcbiAgICAgIGEgKz0gRyhiLCBjLCBkKSArIHggKyAweDdhNmQ3NmU5O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA5OlxuICAgICAgYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBkb2N1bWVudC53cml0ZShcIkJvZ3VzIHJvdW5kIG51bWJlclwiKTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgYSA9IFJPTChhLCBzKSArIGU7XG4gIGMgPSBST0woYywgMTApO1xuXG4gIGEgJj0gMHhmZmZmZmZmZjtcbiAgYiAmPSAweGZmZmZmZmZmO1xuICBjICY9IDB4ZmZmZmZmZmY7XG4gIGQgJj0gMHhmZmZmZmZmZjtcbiAgZSAmPSAweGZmZmZmZmZmO1xuXG4gIHZhciByZXRCbG9jayA9IG5ldyBBcnJheSgpO1xuICByZXRCbG9ja1swXSA9IGE7XG4gIHJldEJsb2NrWzFdID0gYjtcbiAgcmV0QmxvY2tbMl0gPSBjO1xuICByZXRCbG9ja1szXSA9IGQ7XG4gIHJldEJsb2NrWzRdID0gZTtcbiAgcmV0QmxvY2tbNV0gPSB4O1xuICByZXRCbG9ja1s2XSA9IHM7XG5cbiAgcmV0dXJuIHJldEJsb2NrO1xufVxuXG5mdW5jdGlvbiBNRGluaXQoTURidWYpIHtcbiAgTURidWZbMF0gPSAweDY3NDUyMzAxO1xuICBNRGJ1ZlsxXSA9IDB4ZWZjZGFiODk7XG4gIE1EYnVmWzJdID0gMHg5OGJhZGNmZTtcbiAgTURidWZbM10gPSAweDEwMzI1NDc2O1xuICBNRGJ1Zls0XSA9IDB4YzNkMmUxZjA7XG59XG5cbnZhciBST0xzID0gW1xuICBbMTEsIDE0LCAxNSwgMTIsIDUsIDgsIDcsIDksIDExLCAxMywgMTQsIDE1LCA2LCA3LCA5LCA4XSxcbiAgWzcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMl0sXG4gIFsxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDVdLFxuICBbMTEsIDEyLCAxNCwgMTUsIDE0LCAxNSwgOSwgOCwgOSwgMTQsIDUsIDYsIDgsIDYsIDUsIDEyXSxcbiAgWzksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNl0sXG4gIFs4LCA5LCA5LCAxMSwgMTMsIDE1LCAxNSwgNSwgNywgNywgOCwgMTEsIDE0LCAxNCwgMTIsIDZdLFxuICBbOSwgMTMsIDE1LCA3LCAxMiwgOCwgOSwgMTEsIDcsIDcsIDEyLCA3LCA2LCAxNSwgMTMsIDExXSxcbiAgWzksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNV0sXG4gIFsxNSwgNSwgOCwgMTEsIDE0LCAxNCwgNiwgMTQsIDYsIDksIDEyLCA5LCAxMiwgNSwgMTUsIDhdLFxuICBbOCwgNSwgMTIsIDksIDEyLCA1LCAxNCwgNiwgOCwgMTMsIDYsIDUsIDE1LCAxMywgMTEsIDExXVxuXTtcblxudmFyIGluZGV4ZXMgPSBbXG4gIFswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1XSxcbiAgWzcsIDQsIDEzLCAxLCAxMCwgNiwgMTUsIDMsIDEyLCAwLCA5LCA1LCAyLCAxNCwgMTEsIDhdLFxuICBbMywgMTAsIDE0LCA0LCA5LCAxNSwgOCwgMSwgMiwgNywgMCwgNiwgMTMsIDExLCA1LCAxMl0sXG4gIFsxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyXSxcbiAgWzQsIDAsIDUsIDksIDcsIDEyLCAyLCAxMCwgMTQsIDEsIDMsIDgsIDExLCA2LCAxNSwgMTNdLFxuICBbNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMl0sXG4gIFs2LCAxMSwgMywgNywgMCwgMTMsIDUsIDEwLCAxNCwgMTUsIDgsIDEyLCA0LCA5LCAxLCAyXSxcbiAgWzE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTNdLFxuICBbOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNF0sXG4gIFsxMiwgMTUsIDEwLCA0LCAxLCA1LCA4LCA3LCA2LCAyLCAxMywgMTQsIDAsIDMsIDksIDExXVxuXTtcblxuZnVuY3Rpb24gY29tcHJlc3MoTURidWYsIFgpIHtcbiAgYmxvY2tBID0gbmV3IEFycmF5KCk7XG4gIGJsb2NrQiA9IG5ldyBBcnJheSgpO1xuXG4gIHZhciByZXRCbG9jaztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDU7IGkrKykge1xuICAgIGJsb2NrQVtpXSA9IG5ldyBOdW1iZXIoTURidWZbaV0pO1xuICAgIGJsb2NrQltpXSA9IG5ldyBOdW1iZXIoTURidWZbaV0pO1xuICB9XG5cbiAgdmFyIHN0ZXAgPSAwO1xuICBmb3IgKHZhciBqID0gMDsgaiA8IDU7IGorKykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZChcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMCkgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMSkgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMikgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgMykgJSA1XSxcbiAgICAgICAgYmxvY2tBWyhzdGVwICsgNCkgJSA1XSxcbiAgICAgICAgWFtpbmRleGVzW2pdW2ldXSxcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgaik7XG5cbiAgICAgIGJsb2NrQVsoc3RlcCArIDApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDEpICUgNV0gPSByZXRCbG9ja1sxXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDIpICUgNV0gPSByZXRCbG9ja1syXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQVsoc3RlcCArIDQpICUgNV0gPSByZXRCbG9ja1s0XTtcblxuICAgICAgc3RlcCArPSA0O1xuICAgIH1cbiAgfVxuXG4gIHN0ZXAgPSAwO1xuICBmb3IgKHZhciBqID0gNTsgaiA8IDEwOyBqKyspIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHJldEJsb2NrID0gbWl4T25lUm91bmQoXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDApICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDEpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDIpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDMpICUgNV0sXG4gICAgICAgIGJsb2NrQlsoc3RlcCArIDQpICUgNV0sXG4gICAgICAgIFhbaW5kZXhlc1tqXVtpXV0sXG4gICAgICAgIFJPTHNbal1baV0sXG4gICAgICAgIGopO1xuXG4gICAgICBibG9ja0JbKHN0ZXAgKyAwKSAlIDVdID0gcmV0QmxvY2tbMF07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAxKSAlIDVdID0gcmV0QmxvY2tbMV07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAyKSAlIDVdID0gcmV0QmxvY2tbMl07XG4gICAgICBibG9ja0JbKHN0ZXAgKyAzKSAlIDVdID0gcmV0QmxvY2tbM107XG4gICAgICBibG9ja0JbKHN0ZXAgKyA0KSAlIDVdID0gcmV0QmxvY2tbNF07XG5cbiAgICAgIHN0ZXAgKz0gNDtcbiAgICB9XG4gIH1cblxuICBibG9ja0JbM10gKz0gYmxvY2tBWzJdICsgTURidWZbMV07XG4gIE1EYnVmWzFdID0gTURidWZbMl0gKyBibG9ja0FbM10gKyBibG9ja0JbNF07XG4gIE1EYnVmWzJdID0gTURidWZbM10gKyBibG9ja0FbNF0gKyBibG9ja0JbMF07XG4gIE1EYnVmWzNdID0gTURidWZbNF0gKyBibG9ja0FbMF0gKyBibG9ja0JbMV07XG4gIE1EYnVmWzRdID0gTURidWZbMF0gKyBibG9ja0FbMV0gKyBibG9ja0JbMl07XG4gIE1EYnVmWzBdID0gYmxvY2tCWzNdO1xufVxuXG5mdW5jdGlvbiB6ZXJvWChYKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgIFhbaV0gPSAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIE1EZmluaXNoKE1EYnVmLCBzdHJwdHIsIGxzd2xlbiwgbXN3bGVuKSB7XG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGogPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IChsc3dsZW4gJiA2Myk7IGkrKykge1xuICAgIFhbaSA+Pj4gMl0gXj0gKHN0cnB0ci5jaGFyQ29kZUF0KGorKykgJiAyNTUpIDw8ICg4ICogKGkgJiAzKSk7XG4gIH1cblxuICBYWyhsc3dsZW4gPj4+IDIpICYgMTVdIF49IDEgPDwgKDggKiAobHN3bGVuICYgMykgKyA3KTtcblxuICBpZiAoKGxzd2xlbiAmIDYzKSA+IDU1KSB7XG4gICAgY29tcHJlc3MoTURidWYsIFgpO1xuICAgIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgICB6ZXJvWChYKTtcbiAgfVxuXG4gIFhbMTRdID0gbHN3bGVuIDw8IDM7XG4gIFhbMTVdID0gKGxzd2xlbiA+Pj4gMjkpIHwgKG1zd2xlbiA8PCAzKTtcblxuICBjb21wcmVzcyhNRGJ1ZiwgWCk7XG59XG5cbmZ1bmN0aW9uIEJZVEVTX1RPX0RXT1JEKGZvdXJDaGFycykge1xuICB2YXIgdG1wID0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDMpICYgMjU1KSA8PCAyNDtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgyKSAmIDI1NSkgPDwgMTY7XG4gIHRtcCB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMSkgJiAyNTUpIDw8IDg7XG4gIHRtcCB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMCkgJiAyNTUpO1xuXG4gIHJldHVybiB0bXA7XG59XG5cbmZ1bmN0aW9uIFJNRChtZXNzYWdlKSB7XG4gIHZhciBNRGJ1ZiA9IG5ldyBBcnJheShSTURzaXplIC8gMzIpO1xuICB2YXIgaGFzaGNvZGUgPSBuZXcgQXJyYXkoUk1Ec2l6ZSAvIDgpO1xuICB2YXIgbGVuZ3RoO1xuICB2YXIgbmJ5dGVzO1xuXG4gIE1EaW5pdChNRGJ1Zik7XG4gIGxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGogPSAwO1xuICBmb3IgKHZhciBuYnl0ZXMgPSBsZW5ndGg7IG5ieXRlcyA+IDYzOyBuYnl0ZXMgLT0gNjQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIFhbaV0gPSBCWVRFU19UT19EV09SRChtZXNzYWdlLnN1YnN0cihqLCA0KSk7XG4gICAgICBqICs9IDQ7XG4gICAgfVxuICAgIGNvbXByZXNzKE1EYnVmLCBYKTtcbiAgfVxuXG4gIE1EZmluaXNoKE1EYnVmLCBtZXNzYWdlLnN1YnN0cihqKSwgbGVuZ3RoLCAwKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFJNRHNpemUgLyA4OyBpICs9IDQpIHtcbiAgICBoYXNoY29kZVtpXSA9IE1EYnVmW2kgPj4+IDJdICYgMjU1O1xuICAgIGhhc2hjb2RlW2kgKyAxXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gOCkgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDJdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAxNikgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDNdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAyNCkgJiAyNTU7XG4gIH1cblxuICByZXR1cm4gaGFzaGNvZGU7XG59XG5cblxuZnVuY3Rpb24gUk1Ec3RyaW5nKG1lc3NhZ2UpIHtcbiAgdmFyIGhhc2hjb2RlID0gUk1EKG1lc3NhZ2UpO1xuICB2YXIgcmV0U3RyaW5nID0gXCJcIjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFJNRHNpemUgLyA4OyBpKyspIHtcbiAgICByZXRTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoY29kZVtpXSk7XG4gIH1cblxuICByZXR1cm4gcmV0U3RyaW5nO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJNRHN0cmluZztcbiIsIi8qIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU0hBIGZhbWlseSBvZiBoYXNoZXMsIGFzIGRlZmluZWQgaW4gRklQUyBcbiAqIFBVQiAxODAtMiBhcyB3ZWxsIGFzIHRoZSBjb3JyZXNwb25kaW5nIEhNQUMgaW1wbGVtZW50YXRpb24gYXMgZGVmaW5lZCBpblxuICogRklQUyBQVUIgMTk4YVxuICpcbiAqIFZlcnNpb24gMS4zIENvcHlyaWdodCBCcmlhbiBUdXJlayAyMDA4LTIwMTBcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9qc3NoYS5zb3VyY2Vmb3JnZS5uZXQvIGZvciBtb3JlIGluZm9ybWF0aW9uXG4gKlxuICogU2V2ZXJhbCBmdW5jdGlvbnMgdGFrZW4gZnJvbSBQYXVsIEpvaG5zb25cbiAqL1xuXG4vKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqIFxuICogVGhpcyBjb2RlIGhhcyBiZWVuIHNsaWdodGx5IG1vZGlmaWVkIGRpcmVjdCBzdHJpbmcgb3V0cHV0OlxuICogLSBiaW4yYnN0ciBoYXMgYmVlbiBhZGRlZFxuICogLSBmb2xsb3dpbmcgd3JhcHBlcnMgb2YgdGhpcyBsaWJyYXJ5IGhhdmUgYmVlbiBhZGRlZDpcbiAqICAgLSBzdHJfc2hhMVxuICogICAtIHN0cl9zaGEyNTZcbiAqICAgLSBzdHJfc2hhMjI0XG4gKiAgIC0gc3RyX3NoYTM4NFxuICogICAtIHN0cl9zaGE1MTJcbiAqL1xuXG4vKipcbiAqIEBtb2R1bGUgY3J5cHRvL2hhc2gvc2hhXG4gKi9cblxudmFyIGpzU0hBID0gKGZ1bmN0aW9uKCkge1xuXG4gIC8qXG4gICAqIENvbmZpZ3VyYWJsZSB2YXJpYWJsZXMuIERlZmF1bHRzIHR5cGljYWxseSB3b3JrXG4gICAqL1xuICAvKiBOdW1iZXIgb2YgQml0cyBQZXIgY2hhcmFjdGVyICg4IGZvciBBU0NJSSwgMTYgZm9yIFVuaWNvZGUpICovXG4gIHZhciBjaGFyU2l6ZSA9IDgsXG4gICAgLyogYmFzZS02NCBwYWQgY2hhcmFjdGVyLiBcIj1cIiBmb3Igc3RyaWN0IFJGQyBjb21wbGlhbmNlICovXG4gICAgYjY0cGFkID0gXCJcIixcbiAgICAvKiBoZXggb3V0cHV0IGZvcm1hdC4gMCAtIGxvd2VyY2FzZTsgMSAtIHVwcGVyY2FzZSAqL1xuICAgIGhleENhc2UgPSAwLFxuXG4gICAgLypcbiAgICAgKiBJbnRfNjQgaXMgYSBvYmplY3QgZm9yIDIgMzItYml0IG51bWJlcnMgZW11bGF0aW5nIGEgNjQtYml0IG51bWJlclxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1zaW50XzMyIFRoZSBtb3N0IHNpZ25pZmljYW50IDMyLWJpdHMgb2YgYSA2NC1iaXQgbnVtYmVyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxzaW50XzMyIFRoZSBsZWFzdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlclxuICAgICAqL1xuICAgIEludF82NCA9IGZ1bmN0aW9uKG1zaW50XzMyLCBsc2ludF8zMikge1xuICAgICAgdGhpcy5oaWdoT3JkZXIgPSBtc2ludF8zMjtcbiAgICAgIHRoaXMubG93T3JkZXIgPSBsc2ludF8zMjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHNcbiAgICAgKiBJZiBjaGFyU2l6ZSBpcyBBU0NJSSwgY2hhcmFjdGVycyA+MjU1IGhhdmUgdGhlaXIgaGktYnl0ZSBzaWxlbnRseVxuICAgICAqIGlnbm9yZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBiZSBjb252ZXJ0ZWQgdG8gYmluYXJ5IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBJbnRlZ2VyIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBzdHIyYmluYiA9IGZ1bmN0aW9uKHN0cikge1xuICAgICAgdmFyIGJpbiA9IFtdLFxuICAgICAgICBtYXNrID0gKDEgPDwgY2hhclNpemUpIC0gMSxcbiAgICAgICAgbGVuZ3RoID0gc3RyLmxlbmd0aCAqIGNoYXJTaXplLFxuICAgICAgICBpO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGNoYXJTaXplKSB7XG4gICAgICAgIGJpbltpID4+IDVdIHw9IChzdHIuY2hhckNvZGVBdChpIC8gY2hhclNpemUpICYgbWFzaykgPDxcbiAgICAgICAgICAoMzIgLSBjaGFyU2l6ZSAtIChpICUgMzIpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJpbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGEgaGV4IHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBiZSBjb252ZXJ0ZWQgdG8gYmluYXJ5IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBJbnRlZ2VyIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBoZXgyYmluYiA9IGZ1bmN0aW9uKHN0cikge1xuICAgICAgdmFyIGJpbiA9IFtdLFxuICAgICAgICBsZW5ndGggPSBzdHIubGVuZ3RoLFxuICAgICAgICBpLCBudW07XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMikge1xuICAgICAgICBudW0gPSBwYXJzZUludChzdHIuc3Vic3RyKGksIDIpLCAxNik7XG4gICAgICAgIGlmICghaXNOYU4obnVtKSkge1xuICAgICAgICAgIGJpbltpID4+IDNdIHw9IG51bSA8PCAoMjQgLSAoNCAqIChpICUgOCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gXCJJTlZBTElEIEhFWCBTVFJJTkdcIjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYmluO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIGhleCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGJpbmFycmF5IEFycmF5IG9mIGludGVnZXJzIHRvIGJlIGNvbnZlcnRlZCB0byBoZXhpZGVjaW1hbFxuICAgICAqXHQgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcmV0dXJuIEhleGlkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXIgaW4gU3RyaW5nIGZvcm1cbiAgICAgKi9cbiAgICBiaW5iMmhleCA9IGZ1bmN0aW9uKGJpbmFycmF5KSB7XG4gICAgICB2YXIgaGV4X3RhYiA9IChoZXhDYXNlKSA/IFwiMDEyMzQ1Njc4OUFCQ0RFRlwiIDogXCIwMTIzNDU2Nzg5YWJjZGVmXCIsXG4gICAgICAgIHN0ciA9IFwiXCIsXG4gICAgICAgIGxlbmd0aCA9IGJpbmFycmF5Lmxlbmd0aCAqIDQsXG4gICAgICAgIGksIHNyY0J5dGU7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBzcmNCeXRlID0gYmluYXJyYXlbaSA+PiAyXSA+PiAoKDMgLSAoaSAlIDQpKSAqIDgpO1xuICAgICAgICBzdHIgKz0gaGV4X3RhYi5jaGFyQXQoKHNyY0J5dGUgPj4gNCkgJiAweEYpICtcbiAgICAgICAgICBoZXhfdGFiLmNoYXJBdChzcmNCeXRlICYgMHhGKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBiYXNlLTY0IHN0cmluZ1xuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBiaW5hcnJheSBBcnJheSBvZiBpbnRlZ2VycyB0byBiZSBjb252ZXJ0ZWQgdG8gYmFzZS02NFxuICAgICAqXHQgcmVwcmVzZW50YXRpb25cbiAgICAgKiBAcmV0dXJuIEJhc2UtNjQgZW5jb2RlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyIGluIFN0cmluZyBmb3JtXG4gICAgICovXG4gICAgYmluYjJiNjQgPSBmdW5jdGlvbihiaW5hcnJheSkge1xuICAgICAgdmFyIHRhYiA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiICtcbiAgICAgICAgXCIwMTIzNDU2Nzg5Ky9cIixcbiAgICAgICAgc3RyID0gXCJcIixcbiAgICAgICAgbGVuZ3RoID0gYmluYXJyYXkubGVuZ3RoICogNCxcbiAgICAgICAgaSwgaixcbiAgICAgICAgdHJpcGxldDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIHRyaXBsZXQgPSAoKChiaW5hcnJheVtpID4+IDJdID4+IDggKiAoMyAtIGkgJSA0KSkgJiAweEZGKSA8PCAxNikgfFxuICAgICAgICAgICgoKGJpbmFycmF5W2kgKyAxID4+IDJdID4+IDggKiAoMyAtIChpICsgMSkgJSA0KSkgJiAweEZGKSA8PCA4KSB8XG4gICAgICAgICAgKChiaW5hcnJheVtpICsgMiA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDIpICUgNCkpICYgMHhGRik7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCA0OyBqICs9IDEpIHtcbiAgICAgICAgICBpZiAoaSAqIDggKyBqICogNiA8PSBiaW5hcnJheS5sZW5ndGggKiAzMikge1xuICAgICAgICAgICAgc3RyICs9IHRhYi5jaGFyQXQoKHRyaXBsZXQgPj4gNiAqICgzIC0gaikpICYgMHgzRik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0ciArPSBiNjRwYWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIHN0cmluZ1xuICAgICAqL1xuICAgIGJpbmIyc3RyID0gZnVuY3Rpb24oYmluKSB7XG4gICAgICB2YXIgc3RyID0gXCJcIjtcbiAgICAgIHZhciBtYXNrID0gKDEgPDwgOCkgLSAxO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiaW4ubGVuZ3RoICogMzI7IGkgKz0gOClcbiAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGJpbltpID4+IDVdID4+PiAoMjQgLSBpICUgMzIpKSAmIG1hc2spO1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9LFxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgbGVmdFxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnRcbiAgICAgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgY2lyY3VsYXJseSBieSBuIGJpdHNcbiAgICAgKi9cbiAgICByb3RsXzMyID0gZnVuY3Rpb24oeCwgbikge1xuICAgICAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSByaWdodFxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnRcbiAgICAgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgY2lyY3VsYXJseSBieSBuIGJpdHNcbiAgICAgKi9cbiAgICByb3RyXzMyID0gZnVuY3Rpb24oeCwgbikge1xuICAgICAgcmV0dXJuICh4ID4+PiBuKSB8ICh4IDw8ICgzMiAtIG4pKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSByaWdodFxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnRcbiAgICAgKiBAcmV0dXJuIFRoZSB4IHNoaWZ0ZWQgY2lyY3VsYXJseSBieSBuIGJpdHNcbiAgICAgKi9cbiAgICByb3RyXzY0ID0gZnVuY3Rpb24oeCwgbikge1xuICAgICAgaWYgKG4gPD0gMzIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgICh4LmhpZ2hPcmRlciA+Pj4gbikgfCAoeC5sb3dPcmRlciA8PCAoMzIgLSBuKSksICh4Lmxvd09yZGVyID4+PiBuKSB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgICh4Lmxvd09yZGVyID4+PiBuKSB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSksICh4LmhpZ2hPcmRlciA+Pj4gbikgfCAoeC5sb3dPcmRlciA8PCAoMzIgLSBuKSkpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2Ygc2hpZnQgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGJ5IG4gYml0c1xuICAgICAqL1xuICAgIHNocl8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiB4ID4+PiBuO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2Ygc2hpZnQgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGJ5IG4gYml0c1xuICAgICAqL1xuICAgIHNocl82NCA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIGlmIChuIDw9IDMyKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAgIHguaGlnaE9yZGVyID4+PiBuLFxuICAgICAgICAgIHgubG93T3JkZXIgPj4+IG4gfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAgIDAsXG4gICAgICAgICAgeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFBhcml0eSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHogVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHBhcml0eV8zMiA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgQ2ggZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBjaF8zMiA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICAgIHJldHVybiAoeCAmIHkpIF4gKH54ICYgeik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgQ2ggZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHkgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB6IFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBjaF82NCA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgKHguaGlnaE9yZGVyICYgeS5oaWdoT3JkZXIpIF4gKH54LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSwgKHgubG93T3JkZXIgJiB5Lmxvd09yZGVyKSBeICh+eC5sb3dPcmRlciAmIHoubG93T3JkZXIpKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBtYWpfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIE1haiBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHogVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIG1hal82NCA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgKHguaGlnaE9yZGVyICYgeS5oaWdoT3JkZXIpIF5cbiAgICAgICAgKHguaGlnaE9yZGVyICYgei5oaWdoT3JkZXIpIF5cbiAgICAgICAgKHkuaGlnaE9yZGVyICYgei5oaWdoT3JkZXIpLCAoeC5sb3dPcmRlciAmIHkubG93T3JkZXIpIF5cbiAgICAgICAgKHgubG93T3JkZXIgJiB6Lmxvd09yZGVyKSBeXG4gICAgICAgICh5Lmxvd09yZGVyICYgei5sb3dPcmRlcikpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWEwXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgMikgXiByb3RyXzMyKHgsIDEzKSBeIHJvdHJfMzIoeCwgMjIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWEwXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIyOCA9IHJvdHJfNjQoeCwgMjgpLFxuICAgICAgICByb3RyMzQgPSByb3RyXzY0KHgsIDM0KSxcbiAgICAgICAgcm90cjM5ID0gcm90cl82NCh4LCAzOSk7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMjguaGlnaE9yZGVyIF4gcm90cjM0LmhpZ2hPcmRlciBeIHJvdHIzOS5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIyOC5sb3dPcmRlciBeIHJvdHIzNC5sb3dPcmRlciBeIHJvdHIzOS5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWExIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzaWdtYTFfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCA2KSBeIHJvdHJfMzIoeCwgMTEpIF4gcm90cl8zMih4LCAyNSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWExIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBzaWdtYTFfNjQgPSBmdW5jdGlvbih4KSB7XG4gICAgICB2YXIgcm90cjE0ID0gcm90cl82NCh4LCAxNCksXG4gICAgICAgIHJvdHIxOCA9IHJvdHJfNjQoeCwgMTgpLFxuICAgICAgICByb3RyNDEgPSByb3RyXzY0KHgsIDQxKTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgIHJvdHIxNC5oaWdoT3JkZXIgXiByb3RyMTguaGlnaE9yZGVyIF4gcm90cjQxLmhpZ2hPcmRlcixcbiAgICAgICAgcm90cjE0Lmxvd09yZGVyIF4gcm90cjE4Lmxvd09yZGVyIF4gcm90cjQxLmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMF8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDcpIF4gcm90cl8zMih4LCAxOCkgXiBzaHJfMzIoeCwgMyk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTBfNjQgPSBmdW5jdGlvbih4KSB7XG4gICAgICB2YXIgcm90cjEgPSByb3RyXzY0KHgsIDEpLFxuICAgICAgICByb3RyOCA9IHJvdHJfNjQoeCwgOCksXG4gICAgICAgIHNocjcgPSBzaHJfNjQoeCwgNyk7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMS5oaWdoT3JkZXIgXiByb3RyOC5oaWdoT3JkZXIgXiBzaHI3LmhpZ2hPcmRlcixcbiAgICAgICAgcm90cjEubG93T3JkZXIgXiByb3RyOC5sb3dPcmRlciBeIHNocjcubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWExXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgMTcpIF4gcm90cl8zMih4LCAxOSkgXiBzaHJfMzIoeCwgMTApO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWExXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxOSA9IHJvdHJfNjQoeCwgMTkpLFxuICAgICAgICByb3RyNjEgPSByb3RyXzY0KHgsIDYxKSxcbiAgICAgICAgc2hyNiA9IHNocl82NCh4LCA2KTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoXG4gICAgICAgIHJvdHIxOS5oaWdoT3JkZXIgXiByb3RyNjEuaGlnaE9yZGVyIF4gc2hyNi5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxOS5sb3dPcmRlciBeIHJvdHI2MS5sb3dPcmRlciBeIHNocjYubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCB0d28gMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgeCArIHlcbiAgICAgKi9cbiAgICBzYWZlQWRkXzMyXzIgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLFxuICAgICAgICBtc3cgPSAoeCA+Pj4gMTYpICsgKHkgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcblxuICAgICAgcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZm91ciAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkIFRoZSBmb3VydGggMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZFxuICAgICAqL1xuICAgIHNhZmVBZGRfMzJfNCA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQpIHtcbiAgICAgIHZhciBsc3cgPSAoYSAmIDB4RkZGRikgKyAoYiAmIDB4RkZGRikgKyAoYyAmIDB4RkZGRikgKyAoZCAmIDB4RkZGRiksXG4gICAgICAgIG1zdyA9IChhID4+PiAxNikgKyAoYiA+Pj4gMTYpICsgKGMgPj4+IDE2KSArIChkID4+PiAxNikgK1xuICAgICAgICAgIChsc3cgPj4+IDE2KTtcblxuICAgICAgcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZml2ZSAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkIFRoZSBmb3VydGggMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZSBUaGUgZmlmdGggMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZCArIGVcbiAgICAgKi9cbiAgICBzYWZlQWRkXzMyXzUgPSBmdW5jdGlvbihhLCBiLCBjLCBkLCBlKSB7XG4gICAgICB2YXIgbHN3ID0gKGEgJiAweEZGRkYpICsgKGIgJiAweEZGRkYpICsgKGMgJiAweEZGRkYpICsgKGQgJiAweEZGRkYpICtcbiAgICAgICAgKGUgJiAweEZGRkYpLFxuICAgICAgICBtc3cgPSAoYSA+Pj4gMTYpICsgKGIgPj4+IDE2KSArIChjID4+PiAxNikgKyAoZCA+Pj4gMTYpICtcbiAgICAgICAgICAoZSA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuXG4gICAgICByZXR1cm4gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCB0d28gNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgeCArIHlcbiAgICAgKi9cbiAgICBzYWZlQWRkXzY0XzIgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7XG5cbiAgICAgIGxzdyA9ICh4Lmxvd09yZGVyICYgMHhGRkZGKSArICh5Lmxvd09yZGVyICYgMHhGRkZGKTtcbiAgICAgIG1zdyA9ICh4Lmxvd09yZGVyID4+PiAxNikgKyAoeS5sb3dPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgbG93T3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIGxzdyA9ICh4LmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoeS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKG1zdyA+Pj4gMTYpO1xuICAgICAgbXN3ID0gKHguaGlnaE9yZGVyID4+PiAxNikgKyAoeS5oaWdoT3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGhpZ2hPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgcmV0dXJuIG5ldyBJbnRfNjQoaGlnaE9yZGVyLCBsb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZvdXIgNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBhIFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBiIFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYyBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gZCBUaGUgZm91dGggNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZFxuICAgICAqL1xuICAgIHNhZmVBZGRfNjRfNCA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQpIHtcbiAgICAgIHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuICAgICAgbHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMubG93T3JkZXIgJiAweEZGRkYpICsgKGQubG93T3JkZXIgJiAweEZGRkYpO1xuICAgICAgbXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5sb3dPcmRlciA+Pj4gMTYpICsgKGQubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICBsc3cgPSAoYS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGIuaGlnaE9yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoZC5oaWdoT3JkZXIgJiAweEZGRkYpICsgKG1zdyA+Pj4gMTYpO1xuICAgICAgbXN3ID0gKGEuaGlnaE9yZGVyID4+PiAxNikgKyAoYi5oaWdoT3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChjLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGQuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBoaWdoT3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmaXZlIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGUgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQgKyBlXG4gICAgICovXG4gICAgc2FmZUFkZF82NF81ID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSkge1xuICAgICAgdmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG4gICAgICBsc3cgPSAoYS5sb3dPcmRlciAmIDB4RkZGRikgKyAoYi5sb3dPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5sb3dPcmRlciAmIDB4RkZGRikgKyAoZC5sb3dPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoZS5sb3dPcmRlciAmIDB4RkZGRik7XG4gICAgICBtc3cgPSAoYS5sb3dPcmRlciA+Pj4gMTYpICsgKGIubG93T3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChjLmxvd09yZGVyID4+PiAxNikgKyAoZC5sb3dPcmRlciA+Pj4gMTYpICsgKGUubG93T3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChsc3cgPj4+IDE2KTtcbiAgICAgIGxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICBsc3cgPSAoYS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGIuaGlnaE9yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoZC5oaWdoT3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGUuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgPj4+IDE2KSArIChkLmhpZ2hPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGUuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBoaWdoT3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIFNIQS0xIGhhc2ggb2YgdGhlIHN0cmluZyBzZXQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBtZXNzYWdlIFRoZSBiaW5hcnkgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZyB0b1xuICAgICAqXHQgaGFzaFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtZXNzYWdlTGVuIFRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgbWVzc2FnZVxuICAgICAqIEByZXR1cm4gVGhlIGFycmF5IG9mIGludGVnZXJzIHJlcHJlc2VudGluZyB0aGUgU0hBLTEgaGFzaCBvZiBtZXNzYWdlXG4gICAgICovXG4gICAgY29yZVNIQTEgPSBmdW5jdGlvbihtZXNzYWdlLCBtZXNzYWdlTGVuKSB7XG4gICAgICB2YXIgVyA9IFtdLFxuICAgICAgICBhLCBiLCBjLCBkLCBlLCBULCBjaCA9IGNoXzMyLFxuICAgICAgICBwYXJpdHkgPSBwYXJpdHlfMzIsXG4gICAgICAgIG1haiA9IG1hal8zMixcbiAgICAgICAgcm90bCA9IHJvdGxfMzIsXG4gICAgICAgIHNhZmVBZGRfMiA9IHNhZmVBZGRfMzJfMixcbiAgICAgICAgaSwgdCxcbiAgICAgICAgc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81LFxuICAgICAgICBhcHBlbmRlZE1lc3NhZ2VMZW5ndGgsXG4gICAgICAgIEggPSBbXG4gICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwXG4gICAgICAgIF0sXG4gICAgICAgIEsgPSBbXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNlxuICAgICAgICBdO1xuXG4gICAgICAvKiBBcHBlbmQgJzEnIGF0IHRoZSBlbmQgb2YgdGhlIGJpbmFyeSBzdHJpbmcgKi9cbiAgICAgIG1lc3NhZ2VbbWVzc2FnZUxlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIChtZXNzYWdlTGVuICUgMzIpKTtcbiAgICAgIC8qIEFwcGVuZCBsZW5ndGggb2YgYmluYXJ5IHN0cmluZyBpbiB0aGUgcG9zaXRpb24gc3VjaCB0aGF0IHRoZSBuZXdcblx0XHRsZW5ndGggaXMgYSBtdWx0aXBsZSBvZiA1MTIuICBMb2dpYyBkb2VzIG5vdCB3b3JrIGZvciBldmVuIG11bHRpcGxlc1xuXHRcdG9mIDUxMiBidXQgdGhlcmUgY2FuIG5ldmVyIGJlIGV2ZW4gbXVsdGlwbGVzIG9mIDUxMiAqL1xuICAgICAgbWVzc2FnZVsoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTVdID0gbWVzc2FnZUxlbjtcblxuICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBhcHBlbmRlZE1lc3NhZ2VMZW5ndGg7IGkgKz0gMTYpIHtcbiAgICAgICAgYSA9IEhbMF07XG4gICAgICAgIGIgPSBIWzFdO1xuICAgICAgICBjID0gSFsyXTtcbiAgICAgICAgZCA9IEhbM107XG4gICAgICAgIGUgPSBIWzRdO1xuXG4gICAgICAgIGZvciAodCA9IDA7IHQgPCA4MDsgdCArPSAxKSB7XG4gICAgICAgICAgaWYgKHQgPCAxNikge1xuICAgICAgICAgICAgV1t0XSA9IG1lc3NhZ2VbdCArIGldO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBXW3RdID0gcm90bChXW3QgLSAzXSBeIFdbdCAtIDhdIF4gV1t0IC0gMTRdIF4gV1t0IC0gMTZdLCAxKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodCA8IDIwKSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIGNoKGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPCA0MCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBwYXJpdHkoYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAodCA8IDYwKSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIG1haihiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgcGFyaXR5KGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlID0gZDtcbiAgICAgICAgICBkID0gYztcbiAgICAgICAgICBjID0gcm90bChiLCAzMCk7XG4gICAgICAgICAgYiA9IGE7XG4gICAgICAgICAgYSA9IFQ7XG4gICAgICAgIH1cblxuICAgICAgICBIWzBdID0gc2FmZUFkZF8yKGEsIEhbMF0pO1xuICAgICAgICBIWzFdID0gc2FmZUFkZF8yKGIsIEhbMV0pO1xuICAgICAgICBIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pO1xuICAgICAgICBIWzNdID0gc2FmZUFkZF8yKGQsIEhbM10pO1xuICAgICAgICBIWzRdID0gc2FmZUFkZF8yKGUsIEhbNF0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gSDtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBkZXNpcmVkIFNIQS0yIGhhc2ggb2YgdGhlIHN0cmluZyBzZXQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBUaGUgYmluYXJ5IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcgdG8gaGFzaFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gbWVzc2FnZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQS0yIHZhcmlhbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBhcnJheSBvZiBpbnRlZ2VycyByZXByZXNlbnRpbmcgdGhlIFNIQS0yIGhhc2ggb2YgbWVzc2FnZVxuICAgICAqL1xuICAgIGNvcmVTSEEyID0gZnVuY3Rpb24obWVzc2FnZSwgbWVzc2FnZUxlbiwgdmFyaWFudCkge1xuICAgICAgdmFyIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGgsIFQxLCBUMiwgSCwgbnVtUm91bmRzLCBsZW5ndGhQb3NpdGlvbiwgaSwgdCxcbiAgICAgICAgYmluYXJ5U3RyaW5nSW5jLCBiaW5hcnlTdHJpbmdNdWx0LCBzYWZlQWRkXzIsIHNhZmVBZGRfNCwgc2FmZUFkZF81LFxuICAgICAgICBnYW1tYTAsIGdhbW1hMSwgc2lnbWEwLCBzaWdtYTEsIGNoLCBtYWosIEludCwgSywgVyA9IFtdLFxuICAgICAgICBhcHBlbmRlZE1lc3NhZ2VMZW5ndGg7XG5cbiAgICAgIC8qIFNldCB1cCB0aGUgdmFyaW91cyBmdW5jdGlvbiBoYW5kbGVzIGFuZCB2YXJpYWJsZSBmb3IgdGhlIHNwZWNpZmljIFxuICAgICAgICogdmFyaWFudCAqL1xuICAgICAgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTIyNFwiIHx8IHZhcmlhbnQgPT09IFwiU0hBLTI1NlwiKSB7XG4gICAgICAgIC8qIDMyLWJpdCB2YXJpYW50ICovXG4gICAgICAgIG51bVJvdW5kcyA9IDY0O1xuICAgICAgICBsZW5ndGhQb3NpdGlvbiA9ICgoKG1lc3NhZ2VMZW4gKyA2NSkgPj4gOSkgPDwgNCkgKyAxNTtcbiAgICAgICAgYmluYXJ5U3RyaW5nSW5jID0gMTY7XG4gICAgICAgIGJpbmFyeVN0cmluZ011bHQgPSAxO1xuICAgICAgICBJbnQgPSBOdW1iZXI7XG4gICAgICAgIHNhZmVBZGRfMiA9IHNhZmVBZGRfMzJfMjtcbiAgICAgICAgc2FmZUFkZF80ID0gc2FmZUFkZF8zMl80O1xuICAgICAgICBzYWZlQWRkXzUgPSBzYWZlQWRkXzMyXzU7XG4gICAgICAgIGdhbW1hMCA9IGdhbW1hMF8zMjtcbiAgICAgICAgZ2FtbWExID0gZ2FtbWExXzMyO1xuICAgICAgICBzaWdtYTAgPSBzaWdtYTBfMzI7XG4gICAgICAgIHNpZ21hMSA9IHNpZ21hMV8zMjtcbiAgICAgICAgbWFqID0gbWFqXzMyO1xuICAgICAgICBjaCA9IGNoXzMyO1xuICAgICAgICBLID0gW1xuICAgICAgICAgICAgMHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcbiAgICAgICAgICAgIDB4Mzk1NkMyNUIsIDB4NTlGMTExRjEsIDB4OTIzRjgyQTQsIDB4QUIxQzVFRDUsXG4gICAgICAgICAgICAweEQ4MDdBQTk4LCAweDEyODM1QjAxLCAweDI0MzE4NUJFLCAweDU1MEM3REMzLFxuICAgICAgICAgICAgMHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcbiAgICAgICAgICAgIDB4RTQ5QjY5QzEsIDB4RUZCRTQ3ODYsIDB4MEZDMTlEQzYsIDB4MjQwQ0ExQ0MsXG4gICAgICAgICAgICAweDJERTkyQzZGLCAweDRBNzQ4NEFBLCAweDVDQjBBOURDLCAweDc2Rjk4OERBLFxuICAgICAgICAgICAgMHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcbiAgICAgICAgICAgIDB4QzZFMDBCRjMsIDB4RDVBNzkxNDcsIDB4MDZDQTYzNTEsIDB4MTQyOTI5NjcsXG4gICAgICAgICAgICAweDI3QjcwQTg1LCAweDJFMUIyMTM4LCAweDREMkM2REZDLCAweDUzMzgwRDEzLFxuICAgICAgICAgICAgMHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcbiAgICAgICAgICAgIDB4QTJCRkU4QTEsIDB4QTgxQTY2NEIsIDB4QzI0QjhCNzAsIDB4Qzc2QzUxQTMsXG4gICAgICAgICAgICAweEQxOTJFODE5LCAweEQ2OTkwNjI0LCAweEY0MEUzNTg1LCAweDEwNkFBMDcwLFxuICAgICAgICAgICAgMHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcbiAgICAgICAgICAgIDB4MzkxQzBDQjMsIDB4NEVEOEFBNEEsIDB4NUI5Q0NBNEYsIDB4NjgyRTZGRjMsXG4gICAgICAgICAgICAweDc0OEY4MkVFLCAweDc4QTU2MzZGLCAweDg0Qzg3ODE0LCAweDhDQzcwMjA4LFxuICAgICAgICAgICAgMHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuICAgICAgICBdO1xuXG4gICAgICAgIGlmICh2YXJpYW50ID09PSBcIlNIQS0yMjRcIikge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIDB4YzEwNTllZDgsIDB4MzY3Y2Q1MDcsIDB4MzA3MGRkMTcsIDB4ZjcwZTU5MzksXG4gICAgICAgICAgICAgIDB4ZmZjMDBiMzEsIDB4Njg1ODE1MTEsIDB4NjRmOThmYTcsIDB4YmVmYTRmYTRcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIDB4NkEwOUU2NjcsIDB4QkI2N0FFODUsIDB4M0M2RUYzNzIsIDB4QTU0RkY1M0EsXG4gICAgICAgICAgICAgIDB4NTEwRTUyN0YsIDB4OUIwNTY4OEMsIDB4MUY4M0Q5QUIsIDB4NUJFMENEMTlcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiIHx8IHZhcmlhbnQgPT09IFwiU0hBLTUxMlwiKSB7XG4gICAgICAgIC8qIDY0LWJpdCB2YXJpYW50ICovXG4gICAgICAgIG51bVJvdW5kcyA9IDgwO1xuICAgICAgICBsZW5ndGhQb3NpdGlvbiA9ICgoKG1lc3NhZ2VMZW4gKyAxMjgpID4+IDEwKSA8PCA1KSArIDMxO1xuICAgICAgICBiaW5hcnlTdHJpbmdJbmMgPSAzMjtcbiAgICAgICAgYmluYXJ5U3RyaW5nTXVsdCA9IDI7XG4gICAgICAgIEludCA9IEludF82NDtcbiAgICAgICAgc2FmZUFkZF8yID0gc2FmZUFkZF82NF8yO1xuICAgICAgICBzYWZlQWRkXzQgPSBzYWZlQWRkXzY0XzQ7XG4gICAgICAgIHNhZmVBZGRfNSA9IHNhZmVBZGRfNjRfNTtcbiAgICAgICAgZ2FtbWEwID0gZ2FtbWEwXzY0O1xuICAgICAgICBnYW1tYTEgPSBnYW1tYTFfNjQ7XG4gICAgICAgIHNpZ21hMCA9IHNpZ21hMF82NDtcbiAgICAgICAgc2lnbWExID0gc2lnbWExXzY0O1xuICAgICAgICBtYWogPSBtYWpfNjQ7XG4gICAgICAgIGNoID0gY2hfNjQ7XG5cbiAgICAgICAgSyA9IFtcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiksIG5ldyBJbnQoMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCksXG4gICAgICAgICAgICBuZXcgSW50KDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYpLCBuZXcgSW50KDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMpLFxuICAgICAgICAgICAgbmV3IEludCgweDM5NTZjMjViLCAweGYzNDhiNTM4KSwgbmV3IEludCgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg5MjNmODJhNCwgMHhhZjE5NGY5YiksIG5ldyBJbnQoMHhhYjFjNWVkNSwgMHhkYTZkODExOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIpLCBuZXcgSW50KDB4MTI4MzViMDEsIDB4NDU3MDZmYmUpLFxuICAgICAgICAgICAgbmV3IEludCgweDI0MzE4NWJlLCAweDRlZTRiMjhjKSwgbmV3IEludCgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiksIG5ldyBJbnQoMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUpLCBuZXcgSW50KDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQpLFxuICAgICAgICAgICAgbmV3IEludCgweGU0OWI2OWMxLCAweDllZjE0YWQyKSwgbmV3IEludCgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgwZmMxOWRjNiwgMHg4YjhjZDViNSksIG5ldyBJbnQoMHgyNDBjYTFjYywgMHg3N2FjOWM2NSksXG4gICAgICAgICAgICBuZXcgSW50KDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUpLCBuZXcgSW50KDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMpLFxuICAgICAgICAgICAgbmV3IEludCgweDVjYjBhOWRjLCAweGJkNDFmYmQ0KSwgbmV3IEludCgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiksIG5ldyBJbnQoMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCksXG4gICAgICAgICAgICBuZXcgSW50KDB4YjAwMzI3YzgsIDB4OThmYjIxM2YpLCBuZXcgSW50KDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQpLFxuICAgICAgICAgICAgbmV3IEludCgweGM2ZTAwYmYzLCAweDNkYTg4ZmMyKSwgbmV3IEludCgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiksIG5ldyBJbnQoMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MjdiNzBhODUsIDB4NDZkMjJmZmMpLCBuZXcgSW50KDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYpLFxuICAgICAgICAgICAgbmV3IEludCgweDRkMmM2ZGZjLCAweDVhYzQyYWVkKSwgbmV3IEludCgweDUzMzgwZDEzLCAweDlkOTViM2RmKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSksIG5ldyBJbnQoMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYpLCBuZXcgSW50KDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IpLFxuICAgICAgICAgICAgbmV3IEludCgweGEyYmZlOGExLCAweDRjZjEwMzY0KSwgbmV3IEludCgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSksIG5ldyBJbnQoMHhjNzZjNTFhMywgMHgwNjU0YmUzMCksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgpLCBuZXcgSW50KDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTApLFxuICAgICAgICAgICAgbmV3IEludCgweGY0MGUzNTg1LCAweDU3NzEyMDJhKSwgbmV3IEludCgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgxOWE0YzExNiwgMHhiOGQyZDBjOCksIG5ldyBJbnQoMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyksXG4gICAgICAgICAgICBuZXcgSW50KDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTkpLCBuZXcgSW50KDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgpLFxuICAgICAgICAgICAgbmV3IEludCgweDM5MWMwY2IzLCAweGM1Yzk1YTYzKSwgbmV3IEludCgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg1YjljY2E0ZiwgMHg3NzYzZTM3MyksIG5ldyBJbnQoMHg2ODJlNmZmMywgMHhkNmIyYjhhMyksXG4gICAgICAgICAgICBuZXcgSW50KDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMpLCBuZXcgSW50KDB4NzhhNTYzNmYsIDB4NDMxNzJmNjApLFxuICAgICAgICAgICAgbmV3IEludCgweDg0Yzg3ODE0LCAweGExZjBhYjcyKSwgbmV3IEludCgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCksIG5ldyBJbnQoMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSksXG4gICAgICAgICAgICBuZXcgSW50KDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUpLCBuZXcgSW50KDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIpLFxuICAgICAgICAgICAgbmV3IEludCgweGNhMjczZWNlLCAweGVhMjY2MTljKSwgbmV3IEludCgweGQxODZiOGM3LCAweDIxYzBjMjA3KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSksIG5ldyBJbnQoMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEpLCBuZXcgSW50KDB4MGE2MzdkYzUsIDB4YTJjODk4YTYpLFxuICAgICAgICAgICAgbmV3IEludCgweDExM2Y5ODA0LCAweGJlZjkwZGFlKSwgbmV3IEludCgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCksIG5ldyBJbnQoMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyksXG4gICAgICAgICAgICBuZXcgSW50KDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMpLCBuZXcgSW50KDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMpLFxuICAgICAgICAgICAgbmV3IEludCgweDRjYzVkNGJlLCAweGNiM2U0MmI2KSwgbmV3IEludCgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYyksIG5ldyBJbnQoMHg2YzQ0MTk4YywgMHg0YTQ3NTgxNylcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAodmFyaWFudCA9PT0gXCJTSEEtMzg0XCIpIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICBuZXcgSW50KDB4Y2JiYjlkNWQsIDB4YzEwNTllZDgpLCBuZXcgSW50KDB4MDYyOWEyOTJhLCAweDM2N2NkNTA3KSxcbiAgICAgICAgICAgICAgbmV3IEludCgweDkxNTkwMTVhLCAweDMwNzBkZDE3KSwgbmV3IEludCgweDAxNTJmZWNkOCwgMHhmNzBlNTkzOSksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg2NzMzMjY2NywgMHhmZmMwMGIzMSksIG5ldyBJbnQoMHg5OGViNDRhODcsIDB4Njg1ODE1MTEpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4ZGIwYzJlMGQsIDB4NjRmOThmYTcpLCBuZXcgSW50KDB4MDQ3YjU0ODFkLCAweGJlZmE0ZmE0KVxuICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgbmV3IEludCgweDZhMDllNjY3LCAweGYzYmNjOTA4KSwgbmV3IEludCgweGJiNjdhZTg1LCAweDg0Y2FhNzNiKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweDNjNmVmMzcyLCAweGZlOTRmODJiKSwgbmV3IEludCgweGE1NGZmNTNhLCAweDVmMWQzNmYxKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweDUxMGU1MjdmLCAweGFkZTY4MmQxKSwgbmV3IEludCgweDliMDU2ODhjLCAweDJiM2U2YzFmKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweDFmODNkOWFiLCAweGZiNDFiZDZiKSwgbmV3IEludCgweDViZTBjZDE5LCAweDEzN2UyMTc5KVxuICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyogQXBwZW5kICcxJyBhdCB0aGUgZW5kIG9mIHRoZSBiaW5hcnkgc3RyaW5nICovXG4gICAgICBtZXNzYWdlW21lc3NhZ2VMZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBtZXNzYWdlTGVuICUgMzIpO1xuICAgICAgLyogQXBwZW5kIGxlbmd0aCBvZiBiaW5hcnkgc3RyaW5nIGluIHRoZSBwb3NpdGlvbiBzdWNoIHRoYXQgdGhlIG5ld1xuICAgICAgICogbGVuZ3RoIGlzIGNvcnJlY3QgKi9cbiAgICAgIG1lc3NhZ2VbbGVuZ3RoUG9zaXRpb25dID0gbWVzc2FnZUxlbjtcblxuICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBhcHBlbmRlZE1lc3NhZ2VMZW5ndGg7IGkgKz0gYmluYXJ5U3RyaW5nSW5jKSB7XG4gICAgICAgIGEgPSBIWzBdO1xuICAgICAgICBiID0gSFsxXTtcbiAgICAgICAgYyA9IEhbMl07XG4gICAgICAgIGQgPSBIWzNdO1xuICAgICAgICBlID0gSFs0XTtcbiAgICAgICAgZiA9IEhbNV07XG4gICAgICAgIGcgPSBIWzZdO1xuICAgICAgICBoID0gSFs3XTtcblxuICAgICAgICBmb3IgKHQgPSAwOyB0IDwgbnVtUm91bmRzOyB0ICs9IDEpIHtcbiAgICAgICAgICBpZiAodCA8IDE2KSB7XG4gICAgICAgICAgICAvKiBCaXQgb2YgYSBoYWNrIC0gZm9yIDMyLWJpdCwgdGhlIHNlY29uZCB0ZXJtIGlzIGlnbm9yZWQgKi9cbiAgICAgICAgICAgIFdbdF0gPSBuZXcgSW50KG1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpXSxcbiAgICAgICAgICAgICAgbWVzc2FnZVt0ICogYmluYXJ5U3RyaW5nTXVsdCArIGkgKyAxXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIFdbdF0gPSBzYWZlQWRkXzQoXG4gICAgICAgICAgICAgIGdhbW1hMShXW3QgLSAyXSksIFdbdCAtIDddLFxuICAgICAgICAgICAgICBnYW1tYTAoV1t0IC0gMTVdKSwgV1t0IC0gMTZdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBUMSA9IHNhZmVBZGRfNShoLCBzaWdtYTEoZSksIGNoKGUsIGYsIGcpLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICBUMiA9IHNhZmVBZGRfMihzaWdtYTAoYSksIG1haihhLCBiLCBjKSk7XG4gICAgICAgICAgaCA9IGc7XG4gICAgICAgICAgZyA9IGY7XG4gICAgICAgICAgZiA9IGU7XG4gICAgICAgICAgZSA9IHNhZmVBZGRfMihkLCBUMSk7XG4gICAgICAgICAgZCA9IGM7XG4gICAgICAgICAgYyA9IGI7XG4gICAgICAgICAgYiA9IGE7XG4gICAgICAgICAgYSA9IHNhZmVBZGRfMihUMSwgVDIpO1xuICAgICAgICB9XG5cbiAgICAgICAgSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcbiAgICAgICAgSFsxXSA9IHNhZmVBZGRfMihiLCBIWzFdKTtcbiAgICAgICAgSFsyXSA9IHNhZmVBZGRfMihjLCBIWzJdKTtcbiAgICAgICAgSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcbiAgICAgICAgSFs0XSA9IHNhZmVBZGRfMihlLCBIWzRdKTtcbiAgICAgICAgSFs1XSA9IHNhZmVBZGRfMihmLCBIWzVdKTtcbiAgICAgICAgSFs2XSA9IHNhZmVBZGRfMihnLCBIWzZdKTtcbiAgICAgICAgSFs3XSA9IHNhZmVBZGRfMihoLCBIWzddKTtcbiAgICAgIH1cblxuICAgICAgc3dpdGNoICh2YXJpYW50KSB7XG4gICAgICAgIGNhc2UgXCJTSEEtMjI0XCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0sIEhbMV0sIEhbMl0sIEhbM10sXG4gICAgICAgICAgICBIWzRdLCBIWzVdLCBIWzZdXTtcbiAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICByZXR1cm4gSDtcbiAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgSFswXS5oaWdoT3JkZXIsIEhbMF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzFdLmhpZ2hPcmRlciwgSFsxXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbMl0uaGlnaE9yZGVyLCBIWzJdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFszXS5oaWdoT3JkZXIsIEhbM10ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzRdLmhpZ2hPcmRlciwgSFs0XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNV0uaGlnaE9yZGVyLCBIWzVdLmxvd09yZGVyXTtcbiAgICAgICAgY2FzZSBcIlNIQS01MTJcIjpcbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgSFswXS5oaWdoT3JkZXIsIEhbMF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzFdLmhpZ2hPcmRlciwgSFsxXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbMl0uaGlnaE9yZGVyLCBIWzJdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFszXS5oaWdoT3JkZXIsIEhbM10ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzRdLmhpZ2hPcmRlciwgSFs0XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNV0uaGlnaE9yZGVyLCBIWzVdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs2XS5oaWdoT3JkZXIsIEhbNl0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzddLmhpZ2hPcmRlciwgSFs3XS5sb3dPcmRlcl07XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLyogVGhpcyBzaG91bGQgbmV2ZXIgYmUgcmVhY2hlZCAqL1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBqc1NIQSBpcyB0aGUgd29ya2hvcnNlIG9mIHRoZSBsaWJyYXJ5LiAgSW5zdGFudGlhdGUgaXQgd2l0aCB0aGUgc3RyaW5nIHRvXG4gICAgICogYmUgaGFzaGVkIGFzIHRoZSBwYXJhbWV0ZXJcbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzcmNTdHJpbmcgVGhlIHN0cmluZyB0byBiZSBoYXNoZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXRGb3JtYXQgVGhlIGZvcm1hdCBvZiBzcmNTdHJpbmcsIEFTQ0lJIG9yIEhFWFxuICAgICAqL1xuICAgIGpzU0hBID0gZnVuY3Rpb24oc3JjU3RyaW5nLCBpbnB1dEZvcm1hdCkge1xuXG4gICAgICB0aGlzLnNoYTEgPSBudWxsO1xuICAgICAgdGhpcy5zaGEyMjQgPSBudWxsO1xuICAgICAgdGhpcy5zaGEyNTYgPSBudWxsO1xuICAgICAgdGhpcy5zaGEzODQgPSBudWxsO1xuICAgICAgdGhpcy5zaGE1MTIgPSBudWxsO1xuXG4gICAgICB0aGlzLnN0ckJpbkxlbiA9IG51bGw7XG4gICAgICB0aGlzLnN0clRvSGFzaCA9IG51bGw7XG5cbiAgICAgIC8qIENvbnZlcnQgdGhlIGlucHV0IHN0cmluZyBpbnRvIHRoZSBjb3JyZWN0IHR5cGUgKi9cbiAgICAgIGlmIChcIkhFWFwiID09PSBpbnB1dEZvcm1hdCkge1xuICAgICAgICBpZiAoMCAhPT0gKHNyY1N0cmluZy5sZW5ndGggJSAyKSkge1xuICAgICAgICAgIHJldHVybiBcIlRFWFQgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFNcIjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0ckJpbkxlbiA9IHNyY1N0cmluZy5sZW5ndGggKiA0O1xuICAgICAgICB0aGlzLnN0clRvSGFzaCA9IGhleDJiaW5iKHNyY1N0cmluZyk7XG4gICAgICB9IGVsc2UgaWYgKChcIkFTQ0lJXCIgPT09IGlucHV0Rm9ybWF0KSB8fFxuICAgICAgICAoJ3VuZGVmaW5lZCcgPT09IHR5cGVvZihpbnB1dEZvcm1hdCkpKSB7XG4gICAgICAgIHRoaXMuc3RyQmluTGVuID0gc3JjU3RyaW5nLmxlbmd0aCAqIGNoYXJTaXplO1xuICAgICAgICB0aGlzLnN0clRvSGFzaCA9IHN0cjJiaW5iKHNyY1N0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXCJVTktOT1dOIFRFWFQgSU5QVVQgVFlQRVwiO1xuICAgICAgfVxuICAgIH07XG5cbiAganNTSEEucHJvdG90eXBlID0ge1xuICAgIC8qXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBTSEEgaGFzaCBvZiB0aGUgc3RyaW5nIHNwZWNpZmllZCBhdCBpbnN0YW50aWF0aW9uXG4gICAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEgdmFyaWFudCAoU0hBLTEsIFNIQS0yMjQsXG4gICAgICpcdCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmcgKEI2NCBvciBIRVgpXG4gICAgICogQHJldHVybiBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBoYXNoIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkXG4gICAgICovXG4gICAgZ2V0SGFzaDogZnVuY3Rpb24odmFyaWFudCwgZm9ybWF0KSB7XG4gICAgICB2YXIgZm9ybWF0RnVuYyA9IG51bGwsXG4gICAgICAgIG1lc3NhZ2UgPSB0aGlzLnN0clRvSGFzaC5zbGljZSgpO1xuXG4gICAgICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgICAgICBjYXNlIFwiSEVYXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyaGV4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQjY0XCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyYjY0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQVNDSUlcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJzdHI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiRk9STUFUIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGExKSB7XG4gICAgICAgICAgICB0aGlzLnNoYTEgPSBjb3JlU0hBMShtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMSk7XG4gICAgICAgIGNhc2UgXCJTSEEtMjI0XCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMjI0KSB7XG4gICAgICAgICAgICB0aGlzLnNoYTIyNCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEyMjQpO1xuICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTI1Nikge1xuICAgICAgICAgICAgdGhpcy5zaGEyNTYgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMjU2KTtcbiAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGEzODQpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMzg0ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTM4NCk7XG4gICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhNTEyKSB7XG4gICAgICAgICAgICB0aGlzLnNoYTUxMiA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGE1MTIpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkhBU0ggTk9UIFJFQ09HTklaRURcIjtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIEhNQUMgb2YgdGhlIHN0cmluZyBzcGVjaWZpZWQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqIHVzaW5nIHRoZSBrZXkgYW5kIHZhcmlhbnQgcGFyYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSBrZXkgdXNlZCB0byBjYWxjdWxhdGUgdGhlIEhNQUNcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXRGb3JtYXQgVGhlIGZvcm1hdCBvZiBrZXksIEFTQ0lJIG9yIEhFWFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQSB2YXJpYW50IChTSEEtMSwgU0hBLTIyNCxcbiAgICAgKlx0IFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIpXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG91dHB1dEZvcm1hdCBUaGUgZGVzaXJlZCBvdXRwdXQgZm9ybWF0dGluZ1xuICAgICAqXHQgKEI2NCBvciBIRVgpXG4gICAgICogQHJldHVybiBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBoYXNoIGluIHRoZSBmb3JtYXQgc3BlY2lmaWVkXG4gICAgICovXG4gICAgZ2V0SE1BQzogZnVuY3Rpb24oa2V5LCBpbnB1dEZvcm1hdCwgdmFyaWFudCwgb3V0cHV0Rm9ybWF0KSB7XG4gICAgICB2YXIgZm9ybWF0RnVuYywga2V5VG9Vc2UsIGJsb2NrQnl0ZVNpemUsIGJsb2NrQml0U2l6ZSwgaSxcbiAgICAgICAgcmV0VmFsLCBsYXN0QXJyYXlJbmRleCwga2V5QmluTGVuLCBoYXNoQml0U2l6ZSxcbiAgICAgICAga2V5V2l0aElQYWQgPSBbXSxcbiAgICAgICAga2V5V2l0aE9QYWQgPSBbXTtcblxuICAgICAgLyogVmFsaWRhdGUgdGhlIG91dHB1dCBmb3JtYXQgc2VsZWN0aW9uICovXG4gICAgICBzd2l0Y2ggKG91dHB1dEZvcm1hdCkge1xuICAgICAgICBjYXNlIFwiSEVYXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyaGV4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQjY0XCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyYjY0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQVNDSUlcIjpcbiAgICAgICAgICBmb3JtYXRGdW5jID0gYmluYjJzdHI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiRk9STUFUIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG5cbiAgICAgIC8qIFZhbGlkYXRlIHRoZSBoYXNoIHZhcmlhbnQgc2VsZWN0aW9uIGFuZCBzZXQgbmVlZGVkIHZhcmlhYmxlcyAqL1xuICAgICAgc3dpdGNoICh2YXJpYW50KSB7XG4gICAgICAgIGNhc2UgXCJTSEEtMVwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSA2NDtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDE2MDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS0yMjRcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gNjQ7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAyMjQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDY0O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMjU2O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTM4NFwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSAxMjg7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAzODQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDEyODtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDUxMjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJIQVNIIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG5cbiAgICAgIC8qIFZhbGlkYXRlIGlucHV0IGZvcm1hdCBzZWxlY3Rpb24gKi9cbiAgICAgIGlmIChcIkhFWFwiID09PSBpbnB1dEZvcm1hdCkge1xuICAgICAgICAvKiBOaWJibGVzIG11c3QgY29tZSBpbiBwYWlycyAqL1xuICAgICAgICBpZiAoMCAhPT0gKGtleS5sZW5ndGggJSAyKSkge1xuICAgICAgICAgIHJldHVybiBcIktFWSBNVVNUIEJFIElOIEJZVEUgSU5DUkVNRU5UU1wiO1xuICAgICAgICB9XG4gICAgICAgIGtleVRvVXNlID0gaGV4MmJpbmIoa2V5KTtcbiAgICAgICAga2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIDQ7XG4gICAgICB9IGVsc2UgaWYgKFwiQVNDSUlcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAga2V5VG9Vc2UgPSBzdHIyYmluYihrZXkpO1xuICAgICAgICBrZXlCaW5MZW4gPSBrZXkubGVuZ3RoICogY2hhclNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXCJVTktOT1dOIEtFWSBJTlBVVCBUWVBFXCI7XG4gICAgICB9XG5cbiAgICAgIC8qIFRoZXNlIGFyZSB1c2VkIG11bHRpcGxlIHRpbWVzLCBjYWxjdWxhdGUgYW5kIHN0b3JlIHRoZW0gKi9cbiAgICAgIGJsb2NrQml0U2l6ZSA9IGJsb2NrQnl0ZVNpemUgKiA4O1xuICAgICAgbGFzdEFycmF5SW5kZXggPSAoYmxvY2tCeXRlU2l6ZSAvIDQpIC0gMTtcblxuICAgICAgLyogRmlndXJlIG91dCB3aGF0IHRvIGRvIHdpdGggdGhlIGtleSBiYXNlZCBvbiBpdHMgc2l6ZSByZWxhdGl2ZSB0b1xuICAgICAgICogdGhlIGhhc2gncyBibG9jayBzaXplICovXG4gICAgICBpZiAoYmxvY2tCeXRlU2l6ZSA8IChrZXlCaW5MZW4gLyA4KSkge1xuICAgICAgICBpZiAoXCJTSEEtMVwiID09PSB2YXJpYW50KSB7XG4gICAgICAgICAga2V5VG9Vc2UgPSBjb3JlU0hBMShrZXlUb1VzZSwga2V5QmluTGVuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXlUb1VzZSA9IGNvcmVTSEEyKGtleVRvVXNlLCBrZXlCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8qIEZvciBhbGwgdmFyaWFudHMsIHRoZSBibG9jayBzaXplIGlzIGJpZ2dlciB0aGFuIHRoZSBvdXRwdXRcbiAgICAgICAgICogc2l6ZSBzbyB0aGVyZSB3aWxsIG5ldmVyIGJlIGEgdXNlZnVsIGJ5dGUgYXQgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICogc3RyaW5nICovXG4gICAgICAgIGtleVRvVXNlW2xhc3RBcnJheUluZGV4XSAmPSAweEZGRkZGRjAwO1xuICAgICAgfSBlbHNlIGlmIChibG9ja0J5dGVTaXplID4gKGtleUJpbkxlbiAvIDgpKSB7XG4gICAgICAgIC8qIElmIHRoZSBibG9ja0J5dGVTaXplIGlzIGdyZWF0ZXIgdGhhbiB0aGUga2V5IGxlbmd0aCwgdGhlcmVcbiAgICAgICAgICogd2lsbCBhbHdheXMgYmUgYXQgTEVBU1Qgb25lIFwidXNlbGVzc1wiIGJ5dGUgYXQgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICogc3RyaW5nICovXG4gICAgICAgIGtleVRvVXNlW2xhc3RBcnJheUluZGV4XSAmPSAweEZGRkZGRjAwO1xuICAgICAgfVxuXG4gICAgICAvKiBDcmVhdGUgaXBhZCBhbmQgb3BhZCAqL1xuICAgICAgZm9yIChpID0gMDsgaSA8PSBsYXN0QXJyYXlJbmRleDsgaSArPSAxKSB7XG4gICAgICAgIGtleVdpdGhJUGFkW2ldID0ga2V5VG9Vc2VbaV0gXiAweDM2MzYzNjM2O1xuICAgICAgICBrZXlXaXRoT1BhZFtpXSA9IGtleVRvVXNlW2ldIF4gMHg1QzVDNUM1QztcbiAgICAgIH1cblxuICAgICAgLyogQ2FsY3VsYXRlIHRoZSBITUFDICovXG4gICAgICBpZiAoXCJTSEEtMVwiID09PSB2YXJpYW50KSB7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEExKFxuICAgICAgICAgIGtleVdpdGhJUGFkLmNvbmNhdCh0aGlzLnN0clRvSGFzaCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgdGhpcy5zdHJCaW5MZW4pO1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMShcbiAgICAgICAgICBrZXlXaXRoT1BhZC5jb25jYXQocmV0VmFsKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyBoYXNoQml0U2l6ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMihcbiAgICAgICAgICBrZXlXaXRoSVBhZC5jb25jYXQodGhpcy5zdHJUb0hhc2gpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTIoXG4gICAgICAgICAga2V5V2l0aE9QYWQuY29uY2F0KHJldFZhbCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUsIHZhcmlhbnQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gKGZvcm1hdEZ1bmMocmV0VmFsKSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBqc1NIQTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKiogU0hBMSBoYXNoICovXG4gIHNoYTE6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0xXCIsIFwiQVNDSUlcIik7XG4gIH0sXG4gIC8qKiBTSEEyMjQgaGFzaCAqL1xuICBzaGEyMjQ6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0yMjRcIiwgXCJBU0NJSVwiKTtcbiAgfSxcbiAgLyoqIFNIQTI1NiBoYXNoICovXG4gIHNoYTI1NjogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTI1NlwiLCBcIkFTQ0lJXCIpO1xuICB9LFxuICAvKiogU0hBMzg0IGhhc2ggKi9cbiAgc2hhMzg0OiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMzg0XCIsIFwiQVNDSUlcIik7XG5cbiAgfSxcbiAgLyoqIFNIQTUxMiBoYXNoICovXG4gIHNoYTUxMjogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTUxMlwiLCBcIkFTQ0lJXCIpO1xuICB9XG59XG4iLCIvKipcbiAqIEBzZWUgbW9kdWxlOmNyeXB0by9jcnlwdG9cbiAqIEBtb2R1bGUgY3J5cHRvXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL2NpcGhlciAqL1xuICBjaXBoZXI6IHJlcXVpcmUoJy4vY2lwaGVyJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vaGFzaCAqL1xuICBoYXNoOiByZXF1aXJlKCcuL2hhc2gnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9jZmIgKi9cbiAgY2ZiOiByZXF1aXJlKCcuL2NmYi5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL3B1YmxpY19rZXkgKi9cbiAgcHVibGljS2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9zaWduYXR1cmUgKi9cbiAgc2lnbmF0dXJlOiByZXF1aXJlKCcuL3NpZ25hdHVyZS5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL3JhbmRvbSAqL1xuICByYW5kb206IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vcGtjczEgKi9cbiAgcGtjczE6IHJlcXVpcmUoJy4vcGtjczEuanMnKVxuXG59XG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0by5qcycpO1xuXG5mb3IgKHZhciBpIGluIGNyeXB0bylcbiAgbW9kdWxlLmV4cG9ydHNbaV0gPSBjcnlwdG9baV07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIFBLQ1MxIGVuY29kaW5nXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2NyeXB0b1xuICogQHJlcXVpcmVzIGNyeXB0by9oYXNoXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3B1YmxpY19rZXkvanNiblxuICogQHJlcXVpcmVzIGNyeXB0by9yYW5kb21cbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIGNyeXB0by9wa2NzMVxuICovXG5cbi8qKlxuICogQVNOMSBvYmplY3QgaWRlbnRpZmllcnMgZm9yIGhhc2hlcyAoU2VlIFJGQzQ4ODAgNS4yLjIpXG4gKi9cbmhhc2hfaGVhZGVycyA9IG5ldyBBcnJheSgpO1xuaGFzaF9oZWFkZXJzWzFdID0gWzB4MzAsIDB4MjAsIDB4MzAsIDB4MGMsIDB4MDYsIDB4MDgsIDB4MmEsIDB4ODYsIDB4NDgsIDB4ODYsIDB4ZjcsIDB4MGQsIDB4MDIsIDB4MDUsIDB4MDUsIDB4MDAsIDB4MDQsXG4gICAgMHgxMFxuXTtcbmhhc2hfaGVhZGVyc1syXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJiLCAweDBlLCAweDAzLCAweDAyLCAweDFhLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1szXSA9IFsweDMwLCAweDIxLCAweDMwLCAweDA5LCAweDA2LCAweDA1LCAweDJCLCAweDI0LCAweDAzLCAweDAyLCAweDAxLCAweDA1LCAweDAwLCAweDA0LCAweDE0XTtcbmhhc2hfaGVhZGVyc1s4XSA9IFsweDMwLCAweDMxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAxLCAweDA1LCAweDAwLFxuICAgIDB4MDQsIDB4MjBcbl07XG5oYXNoX2hlYWRlcnNbOV0gPSBbMHgzMCwgMHg0MSwgMHgzMCwgMHgwZCwgMHgwNiwgMHgwOSwgMHg2MCwgMHg4NiwgMHg0OCwgMHgwMSwgMHg2NSwgMHgwMywgMHgwNCwgMHgwMiwgMHgwMiwgMHgwNSwgMHgwMCxcbiAgICAweDA0LCAweDMwXG5dO1xuaGFzaF9oZWFkZXJzWzEwXSA9IFsweDMwLCAweDUxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAzLCAweDA1LFxuICAgIDB4MDAsIDB4MDQsIDB4NDBcbl07XG5oYXNoX2hlYWRlcnNbMTFdID0gWzB4MzAsIDB4MzEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDQsIDB4MDUsXG4gICAgMHgwMCwgMHgwNCwgMHgxQ1xuXTtcblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4vY3J5cHRvLmpzJyksXG4gIHJhbmRvbSA9IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL3B1YmxpY19rZXkvanNibi5qcycpLFxuICBoYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbWU6IHtcbiAgICAvKipcbiAgICAgKiBjcmVhdGUgYSBFTUUtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjEpXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgbWVzc2FnZSB0byBiZSBwYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBMZW5ndGggdG8gdGhlIHJlc3VsdGluZyBtZXNzYWdlXG4gICAgICogQHJldHVybiB7U3RyaW5nfSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2VcbiAgICAgKi9cbiAgICBlbmNvZGU6IGZ1bmN0aW9uKG1lc3NhZ2UsIGxlbmd0aCkge1xuICAgICAgaWYgKG1lc3NhZ2UubGVuZ3RoID4gbGVuZ3RoIC0gMTEpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoIC0gbWVzc2FnZS5sZW5ndGggLSAzOyBpKyspIHtcbiAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmFuZG9tLmdldFBzZXVkb1JhbmRvbSgxLCAyNTUpKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgcmVzdWx0ICs9IG1lc3NhZ2U7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBkZWNvZGVzIGEgRU1FLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4yKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIEVNRS1QS0NTMSBwYWRkZWQgbWVzc2FnZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ30gZGVjb2RlZCBtZXNzYWdlIFxuICAgICAqL1xuICAgIGRlY29kZTogZnVuY3Rpb24obWVzc2FnZSwgbGVuKSB7XG4gICAgICBpZiAobWVzc2FnZS5sZW5ndGggPCBsZW4pXG4gICAgICAgIG1lc3NhZ2UgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApICsgbWVzc2FnZTtcbiAgICAgIGlmIChtZXNzYWdlLmxlbmd0aCA8IDEyIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgwKSAhPSAwIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgxKSAhPSAyKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB2YXIgaSA9IDI7XG4gICAgICB3aGlsZSAobWVzc2FnZS5jaGFyQ29kZUF0KGkpICE9IDAgJiYgbWVzc2FnZS5sZW5ndGggPiBpKVxuICAgICAgICBpKys7XG4gICAgICByZXR1cm4gbWVzc2FnZS5zdWJzdHJpbmcoaSArIDEsIG1lc3NhZ2UubGVuZ3RoKTtcbiAgICB9XG4gIH0sXG5cbiAgZW1zYToge1xuXG4gICAgLyoqXG4gICAgICogY3JlYXRlIGEgRU1TQS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMylcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSB1c2VkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBoYXNoZWRcbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleWxlbmd0aCBLZXkgc2l6ZSBvZiB0aGUgcHVibGljIG1waSBpbiBieXRlc1xuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IEhhc2hjb2RlIHdpdGggcGtjczFwYWRkaW5nIGFzIHN0cmluZ1xuICAgICAqL1xuICAgIGVuY29kZTogZnVuY3Rpb24oYWxnbywgZGF0YSwga2V5bGVuZ3RoKSB7XG4gICAgICB2YXIgZGF0YTIgPSBcIlwiO1xuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcbiAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IChrZXlsZW5ndGggLSBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoIC0gMyAtXG4gICAgICAgIGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpOyBpKyspXG5cbiAgICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweGZmKTtcblxuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoX2hlYWRlcnNbYWxnb10ubGVuZ3RoOyBpKyspXG4gICAgICAgIGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaF9oZWFkZXJzW2FsZ29dW2ldKTtcblxuICAgICAgZGF0YTIgKz0gaGFzaC5kaWdlc3QoYWxnbywgZGF0YSk7XG4gICAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGRhdGEyKSwgMTYpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBleHRyYWN0IHRoZSBoYXNoIG91dCBvZiBhbiBFTVNBLVBLQ1MxLXYxLjUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKSBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBIYXNoIGluIHBrY3MxIGVuY29kaW5nXG4gICAgICogQHJldHVybnMge1N0cmluZ30gVGhlIGhhc2ggYXMgc3RyaW5nXG4gICAgICovXG4gICAgZGVjb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgICB2YXIgaSA9IDA7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KDApID09IDApIGkrKztcbiAgICAgIGVsc2UgaWYgKGRhdGEuY2hhckNvZGVBdCgwKSAhPSAxKSByZXR1cm4gLTE7XG4gICAgICBlbHNlIGkrKztcblxuICAgICAgd2hpbGUgKGRhdGEuY2hhckNvZGVBdChpKSA9PSAweEZGKSBpKys7XG4gICAgICBpZiAoZGF0YS5jaGFyQ29kZUF0KGkrKykgIT0gMCkgcmV0dXJuIC0xO1xuICAgICAgdmFyIGogPSAwO1xuICAgICAgZm9yIChqID0gMDsgaiA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggJiYgaiArIGkgPCBkYXRhLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoaiArIGkpICE9IGhhc2hfaGVhZGVyc1thbGdvXVtqXSkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgaSArPSBqO1xuICAgICAgaWYgKGRhdGEuc3Vic3RyaW5nKGkpLmxlbmd0aCA8IGhhc2guZ2V0SGFzaEJ5dGVMZW5ndGgoYWxnbykpIHJldHVybiAtMTtcbiAgICAgIHJldHVybiBkYXRhLnN1YnN0cmluZyhpKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gQSBEaWdpdGFsIHNpZ25hdHVyZSBhbGdvcml0aG0gaW1wbGVtZW50YXRpb25cblxuLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL2hhc2hcbiAqIEByZXF1aXJlcyBjcnlwdG8vcHVibGljX2tleS9qc2JuXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3JhbmRvbVxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgY3J5cHRvL3B1YmxpY19rZXkvZHNhXG4gKi9cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyksXG4gIGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuLi9oYXNoJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyksXG4gIGNvbmZpZyA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZycpO1xuXG5mdW5jdGlvbiBEU0EoKSB7XG4gIC8vIHMxID0gKChnKipzKSBtb2QgcCkgbW9kIHFcbiAgLy8gczEgPSAoKHMqKi0xKSooc2hhLTEobSkrKHMxKngpIG1vZCBxKVxuICBmdW5jdGlvbiBzaWduKGhhc2hhbGdvLCBtLCBnLCBwLCBxLCB4KSB7XG4gICAgLy8gSWYgdGhlIG91dHB1dCBzaXplIG9mIHRoZSBjaG9zZW4gaGFzaCBpcyBsYXJnZXIgdGhhbiB0aGUgbnVtYmVyIG9mXG4gICAgLy8gYml0cyBvZiBxLCB0aGUgaGFzaCByZXN1bHQgaXMgdHJ1bmNhdGVkIHRvIGZpdCBieSB0YWtpbmcgdGhlIG51bWJlclxuICAgIC8vIG9mIGxlZnRtb3N0IGJpdHMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBiaXRzIG9mIHEuICBUaGlzIChwb3NzaWJseVxuICAgIC8vIHRydW5jYXRlZCkgaGFzaCBmdW5jdGlvbiByZXN1bHQgaXMgdHJlYXRlZCBhcyBhIG51bWJlciBhbmQgdXNlZFxuICAgIC8vIGRpcmVjdGx5IGluIHRoZSBEU0Egc2lnbmF0dXJlIGFsZ29yaXRobS5cbiAgICB2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhoYXNoTW9kdWxlLmRpZ2VzdChoYXNoYWxnbywgbSksIHEuYml0TGVuZ3RoKCkpO1xuICAgIHZhciBoYXNoID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGhhc2hlZF9kYXRhKSwgMTYpO1xuICAgIHZhciBrID0gcmFuZG9tLmdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKEJpZ0ludGVnZXIuT05FLmFkZChCaWdJbnRlZ2VyLk9ORSksIHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTtcbiAgICB2YXIgczEgPSAoZy5tb2RQb3coaywgcCkpLm1vZChxKTtcbiAgICB2YXIgczIgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkoczEpKSkpLm1vZChxKTtcbiAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG4gICAgcmVzdWx0WzBdID0gczEudG9NUEkoKTtcbiAgICByZXN1bHRbMV0gPSBzMi50b01QSSgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3RfaGFzaF9hbGdvcml0aG0ocSkge1xuICAgIHZhciB1c2Vyc2V0dGluZyA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgLypcbiAgICAgKiAxMDI0LWJpdCBrZXksIDE2MC1iaXQgcSwgU0hBLTEsIFNIQS0yMjQsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqIDIwNDgtYml0IGtleSwgMjI0LWJpdCBxLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKiAyMDQ4LWJpdCBrZXksIDI1Ni1iaXQgcSwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICogMzA3Mi1iaXQga2V5LCAyNTYtYml0IHEsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqL1xuICAgIHN3aXRjaCAoTWF0aC5yb3VuZChxLmJpdExlbmd0aCgpIC8gOCkpIHtcbiAgICAgIGNhc2UgMjA6XG4gICAgICAgIC8vIDEwMjQgYml0XG4gICAgICAgIGlmICh1c2Vyc2V0dGluZyAhPSAyICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPiAxMSAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nICE9IDEwICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPCA4KVxuICAgICAgICAgIHJldHVybiAyOyAvLyBwcmVmZXIgc2hhMVxuICAgICAgICByZXR1cm4gdXNlcnNldHRpbmc7XG4gICAgICBjYXNlIDI4OlxuICAgICAgICAvLyAyMDQ4IGJpdFxuICAgICAgICBpZiAodXNlcnNldHRpbmcgPiAxMSAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nIDwgOClcbiAgICAgICAgICByZXR1cm4gMTE7XG4gICAgICAgIHJldHVybiB1c2Vyc2V0dGluZztcbiAgICAgIGNhc2UgMzI6XG4gICAgICAgIC8vIDQwOTYgYml0IC8vIHByZWZlciBzaGEyMjRcbiAgICAgICAgaWYgKHVzZXJzZXR0aW5nID4gMTAgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA8IDgpXG4gICAgICAgICAgcmV0dXJuIDg7IC8vIHByZWZlciBzaGEyNTZcbiAgICAgICAgcmV0dXJuIHVzZXJzZXR0aW5nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIkRTQSBzZWxlY3QgaGFzaCBhbGdvcml0aG06IHJldHVybmluZyBudWxsIGZvciBhbiB1bmtub3duIGxlbmd0aCBvZiBxXCIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgIH1cbiAgfVxuICB0aGlzLnNlbGVjdF9oYXNoX2FsZ29yaXRobSA9IHNlbGVjdF9oYXNoX2FsZ29yaXRobTtcblxuICBmdW5jdGlvbiB2ZXJpZnkoaGFzaGFsZ28sIHMxLCBzMiwgbSwgcCwgcSwgZywgeSkge1xuICAgIHZhciBoYXNoZWRfZGF0YSA9IHV0aWwuZ2V0TGVmdE5CaXRzKGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hhbGdvLCBtKSwgcS5iaXRMZW5ndGgoKSk7XG4gICAgdmFyIGhhc2ggPSBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoaGFzaGVkX2RhdGEpLCAxNik7XG4gICAgaWYgKEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczEpID4gMCB8fFxuICAgICAgczEuY29tcGFyZVRvKHEpID4gMCB8fFxuICAgICAgQmlnSW50ZWdlci5aRVJPLmNvbXBhcmVUbyhzMikgPiAwIHx8XG4gICAgICBzMi5jb21wYXJlVG8ocSkgPiAwKSB7XG4gICAgICB1dGlsLnByaW50X2RlYnVnKFwiaW52YWxpZCBEU0EgU2lnbmF0dXJlXCIpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciB3ID0gczIubW9kSW52ZXJzZShxKTtcbiAgICB2YXIgdTEgPSBoYXNoLm11bHRpcGx5KHcpLm1vZChxKTtcbiAgICB2YXIgdTIgPSBzMS5tdWx0aXBseSh3KS5tb2QocSk7XG4gICAgcmV0dXJuIGcubW9kUG93KHUxLCBwKS5tdWx0aXBseSh5Lm1vZFBvdyh1MiwgcCkpLm1vZChwKS5tb2QocSk7XG4gIH1cblxuICAvKlxuXHQgKiB1bnVzZWQgY29kZS4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIHN0YXJ0IHRvIHdyaXRlIGEga2V5IGdlbmVyYXRvclxuXHQgKiBmdW5jdGlvbi5cblx0XG5cdGZ1bmN0aW9uIGdlbmVyYXRlS2V5KGJpdGNvdW50KSB7XG5cdCAgICB2YXIgcWkgPSBuZXcgQmlnSW50ZWdlcihiaXRjb3VudCwgcHJpbWVDZW50ZXJpZSk7XG5cdCAgICB2YXIgcGkgPSBnZW5lcmF0ZVAocSwgNTEyKTtcblx0ICAgIHZhciBnaSA9IGdlbmVyYXRlRyhwLCBxLCBiaXRjb3VudCk7XG5cdCAgICB2YXIgeGk7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgeGkgPSBuZXcgQmlnSW50ZWdlcihxLmJpdENvdW50KCksIHJhbmQpO1xuXHQgICAgfSB3aGlsZSAoeC5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxICYmIHguY29tcGFyZVRvKHEpICE9IC0xKTtcblx0ICAgIHZhciB5aSA9IGcubW9kUG93KHgsIHApO1xuXHQgICAgcmV0dXJuIHt4OiB4aSwgcTogcWksIHA6IHBpLCBnOiBnaSwgeTogeWl9O1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVQKHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIGlmIChiaXRsZW5ndGggJSA2NCAhPSAwKSB7XG5cdCAgICBcdHJldHVybiBmYWxzZTtcblx0ICAgIH1cblx0ICAgIHZhciBwVGVtcDtcblx0ICAgIHZhciBwVGVtcDI7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgcFRlbXAgPSByYW5kb21mbihiaXRjb3VudCwgdHJ1ZSk7XG5cdCAgICAgICAgcFRlbXAyID0gcFRlbXAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgICAgIHBUZW1wID0gcFRlbXAuc3VidHJhY3QocFRlbXAyLnJlbWFpbmRlcihxKSk7XG5cdCAgICB9IHdoaWxlICghcFRlbXAuaXNQcm9iYWJsZVByaW1lKHByaW1lQ2VudGVyaWUpIHx8IHBUZW1wLmJpdExlbmd0aCgpICE9IGwpO1xuXHQgICAgcmV0dXJuIHBUZW1wO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBnZW5lcmF0ZUcocCwgcSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgdmFyIGF1eCA9IHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgdmFyIHBvdyA9IGF1eC5kaXZpZGUocSk7XG5cdCAgICB2YXIgZ1RlbXA7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgZ1RlbXAgPSByYW5kb21mbihiaXRsZW5ndGgpO1xuXHQgICAgfSB3aGlsZSAoZ1RlbXAuY29tcGFyZVRvKGF1eCkgIT0gLTEgJiYgZ1RlbXAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAxKTtcblx0ICAgIHJldHVybiBnVGVtcC5tb2RQb3cocG93LCBwKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlSyhxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICB2YXIgdGVtcEs7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgdGVtcEsgPSByYW5kb21mbihiaXRsZW5ndGgsIGZhbHNlKTtcblx0ICAgIH0gd2hpbGUgKHRlbXBLLmNvbXBhcmVUbyhxKSAhPSAtMSAmJiB0ZW1wSy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxKTtcblx0ICAgIHJldHVybiB0ZW1wSztcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUihxLHApIHtcblx0ICAgIGsgPSBnZW5lcmF0ZUsocSk7XG5cdCAgICB2YXIgciA9IGcubW9kUG93KGssIHApLm1vZChxKTtcblx0ICAgIHJldHVybiByO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVTKGhhc2hmbixrLHIsbSxxLHgpIHtcbiAgICAgICAgdmFyIGhhc2ggPSBoYXNoZm4obSk7XG4gICAgICAgIHMgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkocikpKSkubW9kKHEpO1xuXHQgICAgcmV0dXJuIHM7XG5cdH0gKi9cbiAgdGhpcy5zaWduID0gc2lnbjtcbiAgdGhpcy52ZXJpZnkgPSB2ZXJpZnk7XG4gIC8vIHRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZUtleTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEU0E7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIEVsR2FtYWwgaW1wbGVtZW50YXRpb25cblxuLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3B1YmxpY19rZXkvanNiblxuICogQHJlcXVpcmVzIGNyeXB0by9yYW5kb21cbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIGNyeXB0by9wdWJsaWNfa2V5L2VsZ2FtYWxcbiAqL1xuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gRWxnYW1hbCgpIHtcblxuICBmdW5jdGlvbiBlbmNyeXB0KG0sIGcsIHAsIHkpIHtcbiAgICAvLyAgY2hvb3NlIGsgaW4gezIsLi4uLHAtMn1cbiAgICB2YXIgdHdvID0gQmlnSW50ZWdlci5PTkUuYWRkKEJpZ0ludGVnZXIuT05FKTtcbiAgICB2YXIgcE1pbnVzMiA9IHAuc3VidHJhY3QodHdvKTtcbiAgICB2YXIgayA9IHJhbmRvbS5nZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZSh0d28sIHBNaW51czIpO1xuICAgIGsgPSBrLm1vZChwTWludXMyKS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHZhciBjID0gW107XG4gICAgY1swXSA9IGcubW9kUG93KGssIHApO1xuICAgIGNbMV0gPSB5Lm1vZFBvdyhrLCBwKS5tdWx0aXBseShtKS5tb2QocCk7XG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICBmdW5jdGlvbiBkZWNyeXB0KGMxLCBjMiwgcCwgeCkge1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJFbGdhbWFsIERlY3J5cHQ6XFxuYzE6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzEudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwiYzI6XCIgKyB1dGlsLmhleHN0cmR1bXAoYzIudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwicDpcIiArIHV0aWwuaGV4c3RyZHVtcChwLnRvTVBJKCkpICsgXCJcXG5cIiArXG4gICAgICBcIng6XCIgKyB1dGlsLmhleHN0cmR1bXAoeC50b01QSSgpKSk7XG4gICAgcmV0dXJuIChjMS5tb2RQb3coeCwgcCkubW9kSW52ZXJzZShwKSkubXVsdGlwbHkoYzIpLm1vZChwKTtcbiAgICAvL3ZhciBjID0gYzEucG93KHgpLm1vZEludmVyc2UocCk7IC8vIGMwXi1hIG1vZCBwXG4gICAgLy9yZXR1cm4gYy5tdWx0aXBseShjMikubW9kKHApO1xuICB9XG5cbiAgLy8gc2lnbmluZyBhbmQgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiB1c2luZyBFbGdhbWFsIGlzIG5vdCByZXF1aXJlZCBieSBPcGVuUEdQLlxuICB0aGlzLmVuY3J5cHQgPSBlbmNyeXB0O1xuICB0aGlzLmRlY3J5cHQgPSBkZWNyeXB0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZ2FtYWw7XG4iLCIvKipcbiAqIEByZXF1aXJlcyBjcnlwdG8vcHVibGljX2tleS9kc2FcbiAqIEByZXF1aXJlcyBjcnlwdG8vcHVibGljX2tleS9lbGdhbWFsXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3B1YmxpY19rZXkvcnNhXG4gKiBAbW9kdWxlIGNyeXB0by9wdWJsaWNfa2V5XG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKiogQHNlZSBtb2R1bGU6Y3J5cHRvL3B1YmxpY19rZXkvcnNhICovXG4gIHJzYTogcmVxdWlyZSgnLi9yc2EuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOmNyeXB0by9wdWJsaWNfa2V5L2VsZ2FtYWwgKi9cbiAgZWxnYW1hbDogcmVxdWlyZSgnLi9lbGdhbWFsLmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpjcnlwdG8vcHVibGljX2tleS9kc2EgKi9cbiAgZHNhOiByZXF1aXJlKCcuL2RzYS5qcycpXG59XG4iLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nXG4gKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbiAqIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvXG4gKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG9cbiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZVxuICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMtSVNcIiBBTkQgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgXG4gKiBFWFBSRVNTLCBJTVBMSUVEIE9SIE9USEVSV0lTRSwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIFxuICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgXG4gKlxuICogSU4gTk8gRVZFTlQgU0hBTEwgVE9NIFdVIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElOQ0lERU5UQUwsXG4gKiBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT0YgQU5ZIEtJTkQsIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVJcbiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0ZcbiAqIFRIRSBQT1NTSUJJTElUWSBPRiBEQU1BR0UsIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgQVJJU0lORyBPVVRcbiAqIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKlxuICogSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGFwcGxpZXM6XG4gKlxuICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2VcbiAqIGFuZCBkaXNjbGFpbWVyLlxuICovXG5cblxuLyoqXG4gKiBAcmVxdWlyZXMgdXRpbFxuICogQG1vZHVsZSBjcnlwdG8vcHVibGljX2tleS9qc2JuXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIEJhc2ljIEphdmFTY3JpcHQgQk4gbGlicmFyeSAtIHN1YnNldCB1c2VmdWwgZm9yIFJTQSBlbmNyeXB0aW9uLlxuXG4vLyBCaXRzIHBlciBkaWdpdFxudmFyIGRiaXRzO1xuXG4vLyBKYXZhU2NyaXB0IGVuZ2luZSBhbmFseXNpc1xudmFyIGNhbmFyeSA9IDB4ZGVhZGJlZWZjYWZlO1xudmFyIGpfbG0gPSAoKGNhbmFyeSAmIDB4ZmZmZmZmKSA9PSAweGVmY2FmZSk7XG5cbi8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG5cbmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSwgYiwgYykge1xuICBpZiAoYSAhPSBudWxsKVxuICAgIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSwgYiwgYyk7XG4gICAgZWxzZSBpZiAoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLCAyNTYpO1xuICBlbHNlIHRoaXMuZnJvbVN0cmluZyhhLCBiKTtcbn1cblxuLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlclxuXG5mdW5jdGlvbiBuYmkoKSB7XG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTtcbn1cblxuLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLFxuLy8gYyBpcyBpbml0aWFsIGNhcnJ5LCByZXR1cm5zIGZpbmFsIGNhcnJ5LlxuLy8gYyA8IDMqZHZhbHVlLCB4IDwgMipkdmFsdWUsIHRoaXNfaSA8IGR2YWx1ZVxuLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC5cblxuLy8gYW0xOiB1c2UgYSBzaW5nbGUgbXVsdCBhbmQgZGl2aWRlIHRvIGdldCB0aGUgaGlnaCBiaXRzLFxuLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2Vcbi8vIG1heCBpbnRlcm5hbCB2YWx1ZSA9IDIqZHZhbHVlXjItMipkdmFsdWUgKDwgMl41MylcblxuZnVuY3Rpb24gYW0xKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIHYgPSB4ICogdGhpc1tpKytdICsgd1tqXSArIGM7XG4gICAgYyA9IE1hdGguZmxvb3IodiAvIDB4NDAwMDAwMCk7XG4gICAgd1tqKytdID0gdiAmIDB4M2ZmZmZmZjtcbiAgfVxuICByZXR1cm4gYztcbn1cbi8vIGFtMiBhdm9pZHMgYSBiaWcgbXVsdC1hbmQtZXh0cmFjdCBjb21wbGV0ZWx5LlxuLy8gTWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDw9IDMwIGJlY2F1c2Ugd2UgZG8gYml0d2lzZSBvcHNcbi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSlcblxuZnVuY3Rpb24gYW0yKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4N2ZmZixcbiAgICB4aCA9IHggPj4gMTU7XG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHZhciBsID0gdGhpc1tpXSAmIDB4N2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNTtcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bDtcbiAgICBsID0geGwgKiBsICsgKChtICYgMHg3ZmZmKSA8PCAxNSkgKyB3W2pdICsgKGMgJiAweDNmZmZmZmZmKTtcbiAgICBjID0gKGwgPj4+IDMwKSArIChtID4+PiAxNSkgKyB4aCAqIGggKyAoYyA+Pj4gMzApO1xuICAgIHdbaisrXSA9IGwgJiAweDNmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4vLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG5cbmZ1bmN0aW9uIGFtMyhpLCB4LCB3LCBqLCBjLCBuKSB7XG4gIHZhciB4bCA9IHggJiAweDNmZmYsXG4gICAgeGggPSB4ID4+IDE0O1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDNmZmY7XG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTQ7XG4gICAgdmFyIG0gPSB4aCAqIGwgKyBoICogeGw7XG4gICAgbCA9IHhsICogbCArICgobSAmIDB4M2ZmZikgPDwgMTQpICsgd1tqXSArIGM7XG4gICAgYyA9IChsID4+IDI4KSArIChtID4+IDE0KSArIHhoICogaDtcbiAgICB3W2orK10gPSBsICYgMHhmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLyppZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIFxuXHRuYXZpZ2F0b3IuYXBwTmFtZSA9PSBcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiKSkge1xuICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjtcbiAgZGJpdHMgPSAzMDtcbn1cbmVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yICE9IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3IuYXBwTmFtZSAhPSBcIk5ldHNjYXBlXCIpKSB7Ki9cbkJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0xO1xuZGJpdHMgPSAyNjtcbi8qfVxuZWxzZSB7IC8vIE1vemlsbGEvTmV0c2NhcGUgc2VlbXMgdG8gcHJlZmVyIGFtM1xuICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMztcbiAgZGJpdHMgPSAyODtcbn0qL1xuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRE0gPSAoKDEgPDwgZGJpdHMpIC0gMSk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxIDw8IGRiaXRzKTtcblxudmFyIEJJX0ZQID0gNTI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5GViA9IE1hdGgucG93KDIsIEJJX0ZQKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAgLSBkYml0cztcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYyID0gMiAqIGRiaXRzIC0gQklfRlA7XG5cbi8vIERpZ2l0IGNvbnZlcnNpb25zXG52YXIgQklfUk0gPSBcIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xudmFyIEJJX1JDID0gbmV3IEFycmF5KCk7XG52YXIgcnIsIHZ2O1xucnIgPSBcIjBcIi5jaGFyQ29kZUF0KDApO1xuZm9yICh2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5yciA9IFwiYVwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5yciA9IFwiQVwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5cbmZ1bmN0aW9uIGludDJjaGFyKG4pIHtcbiAgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTtcbn1cblxuZnVuY3Rpb24gaW50QXQocywgaSkge1xuICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07XG4gIHJldHVybiAoYyA9PSBudWxsKSA/IC0xIDogYztcbn1cblxuLy8gKHByb3RlY3RlZCkgY29weSB0aGlzIHRvIHJcblxuZnVuY3Rpb24gYm5wQ29weVRvKHIpIHtcbiAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gdGhpc1tpXTtcbiAgci50ID0gdGhpcy50O1xuICByLnMgPSB0aGlzLnM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVlxuXG5mdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgdGhpcy50ID0gMTtcbiAgdGhpcy5zID0gKHggPCAwKSA/IC0xIDogMDtcbiAgaWYgKHggPiAwKSB0aGlzWzBdID0geDtcbiAgZWxzZSBpZiAoeCA8IC0xKSB0aGlzWzBdID0geCArIERWO1xuICBlbHNlIHRoaXMudCA9IDA7XG59XG5cbi8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWVcblxuZnVuY3Rpb24gbmJ2KGkpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgci5mcm9tSW50KGkpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeFxuXG5mdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsIGIpIHtcbiAgdmFyIGs7XG4gIGlmIChiID09IDE2KSBrID0gNDtcbiAgZWxzZSBpZiAoYiA9PSA4KSBrID0gMztcbiAgZWxzZSBpZiAoYiA9PSAyNTYpIGsgPSA4OyAvLyBieXRlIGFycmF5XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDE7XG4gIGVsc2UgaWYgKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmIChiID09IDQpIGsgPSAyO1xuICBlbHNlIHtcbiAgICB0aGlzLmZyb21SYWRpeChzLCBiKTtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy50ID0gMDtcbiAgdGhpcy5zID0gMDtcbiAgdmFyIGkgPSBzLmxlbmd0aCxcbiAgICBtaSA9IGZhbHNlLFxuICAgIHNoID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgdmFyIHggPSAoayA9PSA4KSA/IHNbaV0gJiAweGZmIDogaW50QXQocywgaSk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIpIG1pID0gdHJ1ZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBtaSA9IGZhbHNlO1xuICAgIGlmIChzaCA9PSAwKVxuICAgICAgdGhpc1t0aGlzLnQrK10gPSB4O1xuICAgIGVsc2UgaWYgKHNoICsgayA+IHRoaXMuREIpIHtcbiAgICAgIHRoaXNbdGhpcy50IC0gMV0gfD0gKHggJiAoKDEgPDwgKHRoaXMuREIgLSBzaCkpIC0gMSkpIDw8IHNoO1xuICAgICAgdGhpc1t0aGlzLnQrK10gPSAoeCA+PiAodGhpcy5EQiAtIHNoKSk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzW3RoaXMudCAtIDFdIHw9IHggPDwgc2g7XG4gICAgc2ggKz0gaztcbiAgICBpZiAoc2ggPj0gdGhpcy5EQikgc2ggLT0gdGhpcy5EQjtcbiAgfVxuICBpZiAoayA9PSA4ICYmIChzWzBdICYgMHg4MCkgIT0gMCkge1xuICAgIHRoaXMucyA9IC0xO1xuICAgIGlmIChzaCA+IDApIHRoaXNbdGhpcy50IC0gMV0gfD0gKCgxIDw8ICh0aGlzLkRCIC0gc2gpKSAtIDEpIDw8IHNoO1xuICB9XG4gIHRoaXMuY2xhbXAoKTtcbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgdGhpcyk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNsYW1wIG9mZiBleGNlc3MgaGlnaCB3b3Jkc1xuXG5mdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgdmFyIGMgPSB0aGlzLnMgJiB0aGlzLkRNO1xuICB3aGlsZSAodGhpcy50ID4gMCAmJiB0aGlzW3RoaXMudCAtIDFdID09IGMpLS10aGlzLnQ7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXhcblxuZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gXCItXCIgKyB0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpO1xuICB2YXIgaztcbiAgaWYgKGIgPT0gMTYpIGsgPSA0O1xuICBlbHNlIGlmIChiID09IDgpIGsgPSAzO1xuICBlbHNlIGlmIChiID09IDIpIGsgPSAxO1xuICBlbHNlIGlmIChiID09IDMyKSBrID0gNTtcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMjtcbiAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpO1xuICB2YXIga20gPSAoMSA8PCBrKSAtIDEsXG4gICAgZCwgbSA9IGZhbHNlLFxuICAgIHIgPSBcIlwiLFxuICAgIGkgPSB0aGlzLnQ7XG4gIHZhciBwID0gdGhpcy5EQiAtIChpICogdGhpcy5EQikgJSBrO1xuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0gPj4gcCkgPiAwKSB7XG4gICAgICBtID0gdHJ1ZTtcbiAgICAgIHIgPSBpbnQyY2hhcihkKTtcbiAgICB9XG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgaWYgKHAgPCBrKSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSAmICgoMSA8PCBwKSAtIDEpKSA8PCAoayAtIHApO1xuICAgICAgICBkIHw9IHRoaXNbLS1pXSA+PiAocCArPSB0aGlzLkRCIC0gayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHRoaXNbaV0gPj4gKHAgLT0gaykpICYga207XG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHRoaXMuREI7XG4gICAgICAgICAgLS1pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZCA+IDApIG0gPSB0cnVlO1xuICAgICAgaWYgKG0pIHIgKz0gaW50MmNoYXIoZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBtID8gciA6IFwiMFwiO1xufVxuXG4vLyAocHVibGljKSAtdGhpc1xuXG5mdW5jdGlvbiBibk5lZ2F0ZSgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgfHRoaXN8XG5cbmZ1bmN0aW9uIGJuQWJzKCkge1xuICByZXR1cm4gKHRoaXMucyA8IDApID8gdGhpcy5uZWdhdGUoKSA6IHRoaXM7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiArIGlmIHRoaXMgPiBhLCAtIGlmIHRoaXMgPCBhLCAwIGlmIGVxdWFsXG5cbmZ1bmN0aW9uIGJuQ29tcGFyZVRvKGEpIHtcbiAgdmFyIHIgPSB0aGlzLnMgLSBhLnM7XG4gIGlmIChyICE9IDApIHJldHVybiByO1xuICB2YXIgaSA9IHRoaXMudDtcbiAgciA9IGkgLSBhLnQ7XG4gIGlmIChyICE9IDApIHJldHVybiByO1xuICB3aGlsZSAoLS1pID49IDApIGlmICgociA9IHRoaXNbaV0gLSBhW2ldKSAhPSAwKSByZXR1cm4gcjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vIHJldHVybnMgYml0IGxlbmd0aCBvZiB0aGUgaW50ZWdlciB4XG5cbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIHIgPSAxLFxuICAgIHQ7XG4gIGlmICgodCA9IHggPj4+IDE2KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSAxNjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDg7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSA0O1xuICB9XG4gIGlmICgodCA9IHggPj4gMikgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gMjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDE7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gXCJ0aGlzXCJcblxuZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gIGlmICh0aGlzLnQgPD0gMCkgcmV0dXJuIDA7XG4gIHJldHVybiB0aGlzLkRCICogKHRoaXMudCAtIDEpICsgbmJpdHModGhpc1t0aGlzLnQgLSAxXSBeICh0aGlzLnMgJiB0aGlzLkRNKSk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREJcblxuZnVuY3Rpb24gYm5wRExTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2kgKyBuXSA9IHRoaXNbaV07XG4gIGZvciAoaSA9IG4gLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHIudCA9IHRoaXMudCArIG47XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQlxuXG5mdW5jdGlvbiBibnBEUlNoaWZ0VG8obiwgcikge1xuICBmb3IgKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2kgLSBuXSA9IHRoaXNbaV07XG4gIHIudCA9IE1hdGgubWF4KHRoaXMudCAtIG4sIDApO1xuICByLnMgPSB0aGlzLnM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG5cblxuZnVuY3Rpb24gYm5wTFNoaWZ0VG8obiwgcikge1xuICB2YXIgYnMgPSBuICUgdGhpcy5EQjtcbiAgdmFyIGNicyA9IHRoaXMuREIgLSBicztcbiAgdmFyIGJtID0gKDEgPDwgY2JzKSAtIDE7XG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpLFxuICAgIGMgPSAodGhpcy5zIDw8IGJzKSAmIHRoaXMuRE0sXG4gICAgaTtcbiAgZm9yIChpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICByW2kgKyBkcyArIDFdID0gKHRoaXNbaV0gPj4gY2JzKSB8IGM7XG4gICAgYyA9ICh0aGlzW2ldICYgYm0pIDw8IGJzO1xuICB9XG4gIGZvciAoaSA9IGRzIC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwO1xuICByW2RzXSA9IGM7XG4gIHIudCA9IHRoaXMudCArIGRzICsgMTtcbiAgci5zID0gdGhpcy5zO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cblxuZnVuY3Rpb24gYm5wUlNoaWZ0VG8obiwgcikge1xuICByLnMgPSB0aGlzLnM7XG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpO1xuICBpZiAoZHMgPj0gdGhpcy50KSB7XG4gICAgci50ID0gMDtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGJzID0gbiAlIHRoaXMuREI7XG4gIHZhciBjYnMgPSB0aGlzLkRCIC0gYnM7XG4gIHZhciBibSA9ICgxIDw8IGJzKSAtIDE7XG4gIHJbMF0gPSB0aGlzW2RzXSA+PiBicztcbiAgZm9yICh2YXIgaSA9IGRzICsgMTsgaSA8IHRoaXMudDsgKytpKSB7XG4gICAgcltpIC0gZHMgLSAxXSB8PSAodGhpc1tpXSAmIGJtKSA8PCBjYnM7XG4gICAgcltpIC0gZHNdID0gdGhpc1tpXSA+PiBicztcbiAgfVxuICBpZiAoYnMgPiAwKSByW3RoaXMudCAtIGRzIC0gMV0gfD0gKHRoaXMucyAmIGJtKSA8PCBjYnM7XG4gIHIudCA9IHRoaXMudCAtIGRzO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIC0gYVxuXG5mdW5jdGlvbiBibnBTdWJUbyhhLCByKSB7XG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHRoaXNbaV0gLSBhW2ldO1xuICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgIGMgPj49IHRoaXMuREI7XG4gIH1cbiAgaWYgKGEudCA8IHRoaXMudCkge1xuICAgIGMgLT0gYS5zO1xuICAgIHdoaWxlIChpIDwgdGhpcy50KSB7XG4gICAgICBjICs9IHRoaXNbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjIC09IGFbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgLT0gYS5zO1xuICB9XG4gIHIucyA9IChjIDwgMCkgPyAtMSA6IDA7XG4gIGlmIChjIDwgLTEpIHJbaSsrXSA9IHRoaXMuRFYgKyBjO1xuICBlbHNlIGlmIChjID4gMCkgcltpKytdID0gYztcbiAgci50ID0gaTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSwgcikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCksXG4gICAgeSA9IGEuYWJzKCk7XG4gIHZhciBpID0geC50O1xuICByLnQgPSBpICsgeS50O1xuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwO1xuICBmb3IgKGkgPSAwOyBpIDwgeS50OyArK2kpIHJbaSArIHgudF0gPSB4LmFtKDAsIHlbaV0sIHIsIGksIDAsIHgudCk7XG4gIHIucyA9IDA7XG4gIHIuY2xhbXAoKTtcbiAgaWYgKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpXG5cbmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpO1xuICB2YXIgaSA9IHIudCA9IDIgKiB4LnQ7XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCB4LnQgLSAxOyArK2kpIHtcbiAgICB2YXIgYyA9IHguYW0oaSwgeFtpXSwgciwgMiAqIGksIDAsIDEpO1xuICAgIGlmICgocltpICsgeC50XSArPSB4LmFtKGkgKyAxLCAyICogeFtpXSwgciwgMiAqIGkgKyAxLCBjLCB4LnQgLSBpIC0gMSkpID49IHguRFYpIHtcbiAgICAgIHJbaSArIHgudF0gLT0geC5EVjtcbiAgICAgIHJbaSArIHgudCArIDFdID0gMTtcbiAgICB9XG4gIH1cbiAgaWYgKHIudCA+IDApIHJbci50IC0gMV0gKz0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSk7XG4gIHIucyA9IDA7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4vLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cblxuZnVuY3Rpb24gYm5wRGl2UmVtVG8obSwgcSwgcikge1xuICB2YXIgcG0gPSBtLmFicygpO1xuICBpZiAocG0udCA8PSAwKSByZXR1cm47XG4gIHZhciBwdCA9IHRoaXMuYWJzKCk7XG4gIGlmIChwdC50IDwgcG0udCkge1xuICAgIGlmIChxICE9IG51bGwpIHEuZnJvbUludCgwKTtcbiAgICBpZiAociAhPSBudWxsKSB0aGlzLmNvcHlUbyhyKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHIgPT0gbnVsbCkgciA9IG5iaSgpO1xuICB2YXIgeSA9IG5iaSgpLFxuICAgIHRzID0gdGhpcy5zLFxuICAgIG1zID0gbS5zO1xuICB2YXIgbnNoID0gdGhpcy5EQiAtIG5iaXRzKHBtW3BtLnQgLSAxXSk7IC8vIG5vcm1hbGl6ZSBtb2R1bHVzXG4gIGlmIChuc2ggPiAwKSB7XG4gICAgcG0ubFNoaWZ0VG8obnNoLCB5KTtcbiAgICBwdC5sU2hpZnRUbyhuc2gsIHIpO1xuICB9IGVsc2Uge1xuICAgIHBtLmNvcHlUbyh5KTtcbiAgICBwdC5jb3B5VG8ocik7XG4gIH1cbiAgdmFyIHlzID0geS50O1xuICB2YXIgeTAgPSB5W3lzIC0gMV07XG4gIGlmICh5MCA9PSAwKSByZXR1cm47XG4gIHZhciB5dCA9IHkwICogKDEgPDwgdGhpcy5GMSkgKyAoKHlzID4gMSkgPyB5W3lzIC0gMl0gPj4gdGhpcy5GMiA6IDApO1xuICB2YXIgZDEgPSB0aGlzLkZWIC8geXQsXG4gICAgZDIgPSAoMSA8PCB0aGlzLkYxKSAvIHl0LFxuICAgIGUgPSAxIDw8IHRoaXMuRjI7XG4gIHZhciBpID0gci50LFxuICAgIGogPSBpIC0geXMsXG4gICAgdCA9IChxID09IG51bGwpID8gbmJpKCkgOiBxO1xuICB5LmRsU2hpZnRUbyhqLCB0KTtcbiAgaWYgKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICByW3IudCsrXSA9IDE7XG4gICAgci5zdWJUbyh0LCByKTtcbiAgfVxuICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oeXMsIHQpO1xuICB0LnN1YlRvKHksIHkpOyAvLyBcIm5lZ2F0aXZlXCIgeSBzbyB3ZSBjYW4gcmVwbGFjZSBzdWIgd2l0aCBhbSBsYXRlclxuICB3aGlsZSAoeS50IDwgeXMpIHlbeS50KytdID0gMDtcbiAgd2hpbGUgKC0taiA+PSAwKSB7XG4gICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXRcbiAgICB2YXIgcWQgPSAoclstLWldID09IHkwKSA/IHRoaXMuRE0gOiBNYXRoLmZsb29yKHJbaV0gKiBkMSArIChyW2kgLSAxXSArIGUpICogZDIpO1xuICAgIGlmICgocltpXSArPSB5LmFtKDAsIHFkLCByLCBqLCAwLCB5cykpIDwgcWQpIHsgLy8gVHJ5IGl0IG91dFxuICAgICAgeS5kbFNoaWZ0VG8oaiwgdCk7XG4gICAgICByLnN1YlRvKHQsIHIpO1xuICAgICAgd2hpbGUgKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQsIHIpO1xuICAgIH1cbiAgfVxuICBpZiAocSAhPSBudWxsKSB7XG4gICAgci5kclNoaWZ0VG8oeXMsIHEpO1xuICAgIGlmICh0cyAhPSBtcykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHEsIHEpO1xuICB9XG4gIHIudCA9IHlzO1xuICByLmNsYW1wKCk7XG4gIGlmIChuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCwgcik7IC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICBpZiAodHMgPCAwKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ociwgcik7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgbW9kIGFcblxuZnVuY3Rpb24gYm5Nb2QoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmFicygpLmRpdlJlbVRvKGEsIG51bGwsIHIpO1xuICBpZiAodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIE1vZHVsYXIgcmVkdWN0aW9uIHVzaW5nIFwiY2xhc3NpY1wiIGFsZ29yaXRobVxuXG5mdW5jdGlvbiBDbGFzc2ljKG0pIHtcbiAgdGhpcy5tID0gbTtcbn1cblxuZnVuY3Rpb24gY0NvbnZlcnQoeCkge1xuICBpZiAoeC5zIDwgMCB8fCB4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHJldHVybiB4Lm1vZCh0aGlzLm0pO1xuICBlbHNlIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiBjUmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGNSZWR1Y2UoeCkge1xuICB4LmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgeCk7XG59XG5cbmZ1bmN0aW9uIGNNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbmZ1bmN0aW9uIGNTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5DbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7XG5DbGFzc2ljLnByb3RvdHlwZS5yZXZlcnQgPSBjUmV2ZXJ0O1xuQ2xhc3NpYy5wcm90b3R5cGUucmVkdWNlID0gY1JlZHVjZTtcbkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvO1xuQ2xhc3NpYy5wcm90b3R5cGUuc3FyVG8gPSBjU3FyVG87XG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiBcIi0xL3RoaXMgJSAyXkRCXCI7IHVzZWZ1bCBmb3IgTW9udC4gcmVkdWN0aW9uXG4vLyBqdXN0aWZpY2F0aW9uOlxuLy8gICAgICAgICB4eSA9PSAxIChtb2QgbSlcbi8vICAgICAgICAgeHkgPSAgMStrbVxuLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKVxuLy8geFt5KDIteHkpXSA9IDEta14ybV4yXG4vLyB4W3koMi14eSldID09IDEgKG1vZCBtXjIpXG4vLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yXG4vLyBzaG91bGQgcmVkdWNlIHggYW5kIHkoMi14eSkgYnkgbV4yIGF0IGVhY2ggc3RlcCB0byBrZWVwIHNpemUgYm91bmRlZC5cbi8vIEpTIG11bHRpcGx5IFwib3ZlcmZsb3dzXCIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS5cblxuZnVuY3Rpb24gYm5wSW52RGlnaXQoKSB7XG4gIGlmICh0aGlzLnQgPCAxKSByZXR1cm4gMDtcbiAgdmFyIHggPSB0aGlzWzBdO1xuICBpZiAoKHggJiAxKSA9PSAwKSByZXR1cm4gMDtcbiAgdmFyIHkgPSB4ICYgMzsgLy8geSA9PSAxL3ggbW9kIDJeMlxuICB5ID0gKHkgKiAoMiAtICh4ICYgMHhmKSAqIHkpKSAmIDB4ZjsgLy8geSA9PSAxL3ggbW9kIDJeNFxuICB5ID0gKHkgKiAoMiAtICh4ICYgMHhmZikgKiB5KSkgJiAweGZmOyAvLyB5ID09IDEveCBtb2QgMl44XG4gIHkgPSAoeSAqICgyIC0gKCgoeCAmIDB4ZmZmZikgKiB5KSAmIDB4ZmZmZikpKSAmIDB4ZmZmZjsgLy8geSA9PSAxL3ggbW9kIDJeMTZcbiAgLy8gbGFzdCBzdGVwIC0gY2FsY3VsYXRlIGludmVyc2UgbW9kIERWIGRpcmVjdGx5O1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgeSA9ICh5ICogKDIgLSB4ICogeSAlIHRoaXMuRFYpKSAlIHRoaXMuRFY7IC8vIHkgPT0gMS94IG1vZCAyXmRiaXRzXG4gIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWXG4gIHJldHVybiAoeSA+IDApID8gdGhpcy5EViAtIHkgOiAteTtcbn1cblxuLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cblxuZnVuY3Rpb24gTW9udGdvbWVyeShtKSB7XG4gIHRoaXMubSA9IG07XG4gIHRoaXMubXAgPSBtLmludkRpZ2l0KCk7XG4gIHRoaXMubXBsID0gdGhpcy5tcCAmIDB4N2ZmZjtcbiAgdGhpcy5tcGggPSB0aGlzLm1wID4+IDE1O1xuICB0aGlzLnVtID0gKDEgPDwgKG0uREIgLSAxNSkpIC0gMTtcbiAgdGhpcy5tdDIgPSAyICogbS50O1xufVxuXG4vLyB4UiBtb2QgbVxuXG5mdW5jdGlvbiBtb250Q29udmVydCh4KSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHguYWJzKCkuZGxTaGlmdFRvKHRoaXMubS50LCByKTtcbiAgci5kaXZSZW1Ubyh0aGlzLm0sIG51bGwsIHIpO1xuICBpZiAoeC5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgdGhpcy5tLnN1YlRvKHIsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8geC9SIG1vZCBtXG5cbmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkge1xuICB2YXIgciA9IG5iaSgpO1xuICB4LmNvcHlUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG4gIHJldHVybiByO1xufVxuXG4vLyB4ID0geC9SIG1vZCBtIChIQUMgMTQuMzIpXG5cbmZ1bmN0aW9uIG1vbnRSZWR1Y2UoeCkge1xuICB3aGlsZSAoeC50IDw9IHRoaXMubXQyKSAvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXJcbiAgICB4W3gudCsrXSA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tLnQ7ICsraSkge1xuICAgIC8vIGZhc3RlciB3YXkgb2YgY2FsY3VsYXRpbmcgdTAgPSB4W2ldKm1wIG1vZCBEVlxuICAgIHZhciBqID0geFtpXSAmIDB4N2ZmZjtcbiAgICB2YXIgdTAgPSAoaiAqIHRoaXMubXBsICsgKCgoaiAqIHRoaXMubXBoICsgKHhbaV0gPj4gMTUpICogdGhpcy5tcGwpICYgdGhpcy51bSkgPDwgMTUpKSAmIHguRE07XG4gICAgLy8gdXNlIGFtIHRvIGNvbWJpbmUgdGhlIG11bHRpcGx5LXNoaWZ0LWFkZCBpbnRvIG9uZSBjYWxsXG4gICAgaiA9IGkgKyB0aGlzLm0udDtcbiAgICB4W2pdICs9IHRoaXMubS5hbSgwLCB1MCwgeCwgaSwgMCwgdGhpcy5tLnQpO1xuICAgIC8vIHByb3BhZ2F0ZSBjYXJyeVxuICAgIHdoaWxlICh4W2pdID49IHguRFYpIHtcbiAgICAgIHhbal0gLT0geC5EVjtcbiAgICAgIHhbKytqXSsrO1xuICAgIH1cbiAgfVxuICB4LmNsYW1wKCk7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50LCB4KTtcbiAgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0sIHgpO1xufVxuXG4vLyByID0gXCJ4XjIvUiBtb2QgbVwiOyB4ICE9IHJcblxuZnVuY3Rpb24gbW9udFNxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbi8vIHIgPSBcInh5L1IgbW9kIG1cIjsgeCx5ICE9IHJcblxuZnVuY3Rpb24gbW9udE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0O1xuTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydDtcbk1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2U7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbztcbk1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvO1xuXG4vLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW5cblxuZnVuY3Rpb24gYm5wSXNFdmVuKCkge1xuICByZXR1cm4gKCh0aGlzLnQgPiAwKSA/ICh0aGlzWzBdICYgMSkgOiB0aGlzLnMpID09IDA7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggXCJyXCIgKEhBQyAxNC43OSlcblxuZnVuY3Rpb24gYm5wRXhwKGUsIHopIHtcbiAgaWYgKGUgPiAweGZmZmZmZmZmIHx8IGUgPCAxKSByZXR1cm4gQmlnSW50ZWdlci5PTkU7XG4gIHZhciByID0gbmJpKCksXG4gICAgcjIgPSBuYmkoKSxcbiAgICBnID0gei5jb252ZXJ0KHRoaXMpLFxuICAgIGkgPSBuYml0cyhlKSAtIDE7XG4gIGcuY29weVRvKHIpO1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB6LnNxclRvKHIsIHIyKTtcbiAgICBpZiAoKGUgJiAoMSA8PCBpKSkgPiAwKSB6Lm11bFRvKHIyLCBnLCByKTtcbiAgICBlbHNlIHtcbiAgICAgIHZhciB0ID0gcjtcbiAgICAgIHIgPSByMjtcbiAgICAgIHIyID0gdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xufVxuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtLCAwIDw9IGUgPCAyXjMyXG5cbmZ1bmN0aW9uIGJuTW9kUG93SW50KGUsIG0pIHtcbiAgdmFyIHo7XG4gIGlmIChlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG4gIHJldHVybiB0aGlzLmV4cChlLCB6KTtcbn1cblxuLy8gcHJvdGVjdGVkXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tSW50ID0gYm5wRnJvbUludDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21TdHJpbmcgPSBibnBGcm9tU3RyaW5nO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRsU2hpZnRUbyA9IGJucERMU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRyU2hpZnRUbyA9IGJucERSU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5yU2hpZnRUbyA9IGJucFJTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3ViVG8gPSBibnBTdWJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlVG8gPSBibnBTcXVhcmVUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdlJlbVRvID0gYm5wRGl2UmVtVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaXNFdmVuID0gYm5wSXNFdmVuO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZXhwID0gYm5wRXhwO1xuXG4vLyBwdWJsaWNcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvU3RyaW5nID0gYm5Ub1N0cmluZztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYWJzID0gYm5BYnM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jb21wYXJlVG8gPSBibkNvbXBhcmVUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kID0gYm5Nb2Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3dJbnQgPSBibk1vZFBvd0ludDtcblxuLy8gXCJjb25zdGFudHNcIlxuQmlnSW50ZWdlci5aRVJPID0gbmJ2KDApO1xuQmlnSW50ZWdlci5PTkUgPSBuYnYoMSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmlnSW50ZWdlcjtcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuLypcbiAqIENvcHlyaWdodCAoYykgMjAwMy0yMDA1ICBUb20gV3UgKHRqd0Bjcy5TdGFuZm9yZC5FRFUpIFxuICogQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmdcbiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuICogXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4gKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4gKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG9cbiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0b1xuICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG4gKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUy1JU1wiIEFORCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBcbiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgXG4gKiBXQVJSQU5UWSBPRiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBcbiAqXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCxcbiAqIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPRiBBTlkgS0lORCwgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUlxuICogUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBPUiBOT1QgQURWSVNFRCBPRlxuICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVFxuICogT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczpcbiAqXG4gKiBBbGwgcmVkaXN0cmlidXRpb25zIG11c3QgcmV0YWluIGFuIGludGFjdCBjb3B5IG9mIHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYW5kIGRpc2NsYWltZXIuXG4gKi9cblxuXG4vLyBFeHRlbmRlZCBKYXZhU2NyaXB0IEJOIGZ1bmN0aW9ucywgcmVxdWlyZWQgZm9yIFJTQSBwcml2YXRlIG9wcy5cblxuLy8gVmVyc2lvbiAxLjE6IG5ldyBCaWdJbnRlZ2VyKFwiMFwiLCAxMCkgcmV0dXJucyBcInByb3BlclwiIHplcm9cbi8vIFZlcnNpb24gMS4yOiBzcXVhcmUoKSBBUEksIGlzUHJvYmFibGVQcmltZSBmaXhcblxuLy8gKHB1YmxpYylcbmZ1bmN0aW9uIGJuQ2xvbmUoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuY29weVRvKHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcblxuZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHtcbiAgaWYgKHRoaXMucyA8IDApIHtcbiAgICBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdIC0gdGhpcy5EVjtcbiAgICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIC0xO1xuICB9IGVsc2UgaWYgKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXTtcbiAgZWxzZSBpZiAodGhpcy50ID09IDApIHJldHVybiAwO1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICByZXR1cm4gKCh0aGlzWzFdICYgKCgxIDw8ICgzMiAtIHRoaXMuREIpKSAtIDEpKSA8PCB0aGlzLkRCKSB8IHRoaXNbMF07XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBieXRlXG5cbmZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDI0KSA+PiAyNDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIHNob3J0IChhc3N1bWVzIERCPj0xNilcblxuZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDE2KSA+PiAxNjtcbn1cblxuLy8gKHByb3RlY3RlZCkgcmV0dXJuIHggcy50LiByXnggPCBEVlxuXG5mdW5jdGlvbiBibnBDaHVua1NpemUocikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMiAqIHRoaXMuREIgLyBNYXRoLmxvZyhyKSk7XG59XG5cbi8vIChwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwXG5cbmZ1bmN0aW9uIGJuU2lnTnVtKCkge1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIC0xO1xuICBlbHNlIGlmICh0aGlzLnQgPD0gMCB8fCAodGhpcy50ID09IDEgJiYgdGhpc1swXSA8PSAwKSkgcmV0dXJuIDA7XG4gIGVsc2UgcmV0dXJuIDE7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgdG8gcmFkaXggc3RyaW5nXG5cbmZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTA7XG4gIGlmICh0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gXCIwXCI7XG4gIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICB2YXIgYSA9IE1hdGgucG93KGIsIGNzKTtcbiAgdmFyIGQgPSBuYnYoYSksXG4gICAgeSA9IG5iaSgpLFxuICAgIHogPSBuYmkoKSxcbiAgICByID0gXCJcIjtcbiAgdGhpcy5kaXZSZW1UbyhkLCB5LCB6KTtcbiAgd2hpbGUgKHkuc2lnbnVtKCkgPiAwKSB7XG4gICAgciA9IChhICsgei5pbnRWYWx1ZSgpKS50b1N0cmluZyhiKS5zdWJzdHIoMSkgKyByO1xuICAgIHkuZGl2UmVtVG8oZCwgeSwgeik7XG4gIH1cbiAgcmV0dXJuIHouaW50VmFsdWUoKS50b1N0cmluZyhiKSArIHI7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmdcblxuZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsIGIpIHtcbiAgdGhpcy5mcm9tSW50KDApO1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTA7XG4gIHZhciBjcyA9IHRoaXMuY2h1bmtTaXplKGIpO1xuICB2YXIgZCA9IE1hdGgucG93KGIsIGNzKSxcbiAgICBtaSA9IGZhbHNlLFxuICAgIGogPSAwLFxuICAgIHcgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgeCA9IGludEF0KHMsIGkpO1xuICAgIGlmICh4IDwgMCkge1xuICAgICAgaWYgKHMuY2hhckF0KGkpID09IFwiLVwiICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHcgPSBiICogdyArIHg7XG4gICAgaWYgKCsraiA+PSBjcykge1xuICAgICAgdGhpcy5kTXVsdGlwbHkoZCk7XG4gICAgICB0aGlzLmRBZGRPZmZzZXQodywgMCk7XG4gICAgICBqID0gMDtcbiAgICAgIHcgPSAwO1xuICAgIH1cbiAgfVxuICBpZiAoaiA+IDApIHtcbiAgICB0aGlzLmRNdWx0aXBseShNYXRoLnBvdyhiLCBqKSk7XG4gICAgdGhpcy5kQWRkT2Zmc2V0KHcsIDApO1xuICB9XG4gIGlmIChtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHRoaXMpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBhbHRlcm5hdGUgY29uc3RydWN0b3JcblxuZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLCBiLCBjKSB7XG4gIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBiKSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LGludCxSTkcpXG4gICAgaWYgKGEgPCAyKSB0aGlzLmZyb21JbnQoMSk7XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmZyb21OdW1iZXIoYSwgYyk7XG4gICAgICBpZiAoIXRoaXMudGVzdEJpdChhIC0gMSkpIC8vIGZvcmNlIE1TQiBzZXRcbiAgICAgICAgdGhpcy5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgb3Bfb3IsIHRoaXMpO1xuICAgICAgaWYgKHRoaXMuaXNFdmVuKCkpIHRoaXMuZEFkZE9mZnNldCgxLCAwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICB3aGlsZSAoIXRoaXMuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgIHRoaXMuZEFkZE9mZnNldCgyLCAwKTtcbiAgICAgICAgaWYgKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKVxuICAgIHZhciB4ID0gbmV3IEFycmF5KCksXG4gICAgICB0ID0gYSAmIDc7XG4gICAgeC5sZW5ndGggPSAoYSA+PiAzKSArIDE7XG4gICAgYi5uZXh0Qnl0ZXMoeCk7XG4gICAgaWYgKHQgPiAwKSB4WzBdICY9ICgoMSA8PCB0KSAtIDEpO1xuICAgIGVsc2UgeFswXSA9IDA7XG4gICAgdGhpcy5mcm9tU3RyaW5nKHgsIDI1Nik7XG4gIH1cbn1cblxuLy8gKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheVxuXG5mdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICB2YXIgaSA9IHRoaXMudCxcbiAgICByID0gbmV3IEFycmF5KCk7XG4gIHJbMF0gPSB0aGlzLnM7XG4gIHZhciBwID0gdGhpcy5EQiAtIChpICogdGhpcy5EQikgJSA4LFxuICAgIGQsIGsgPSAwO1xuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXNbaV0gPj4gcCkgIT0gKHRoaXMucyAmIHRoaXMuRE0pID4+IHApXG4gICAgICByW2srK10gPSBkIHwgKHRoaXMucyA8PCAodGhpcy5EQiAtIHApKTtcbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IDgpIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8ICg4IC0gcCk7XG4gICAgICAgIGQgfD0gdGhpc1stLWldID4+IChwICs9IHRoaXMuREIgLSA4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSA+PiAocCAtPSA4KSkgJiAweGZmO1xuICAgICAgICBpZiAocCA8PSAwKSB7XG4gICAgICAgICAgcCArPSB0aGlzLkRCO1xuICAgICAgICAgIC0taTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy9pZigoZCYweDgwKSAhPSAwKSBkIHw9IC0yNTY7XG4gICAgICAvL2lmKGsgPT0gMCAmJiAodGhpcy5zJjB4ODApICE9IChkJjB4ODApKSArK2s7XG4gICAgICBpZiAoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBibkVxdWFscyhhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPT0gMCk7XG59XG5cbmZ1bmN0aW9uIGJuTWluKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA8IDApID8gdGhpcyA6IGE7XG59XG5cbmZ1bmN0aW9uIGJuTWF4KGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA+IDApID8gdGhpcyA6IGE7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpXG5cbmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLCBvcCwgcikge1xuICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCwgdGhpcy50KTtcbiAgZm9yIChpID0gMDsgaSA8IG07ICsraSkgcltpXSA9IG9wKHRoaXNbaV0sIGFbaV0pO1xuICBpZiAoYS50IDwgdGhpcy50KSB7XG4gICAgZiA9IGEucyAmIHRoaXMuRE07XG4gICAgZm9yIChpID0gbTsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gb3AodGhpc1tpXSwgZik7XG4gICAgci50ID0gdGhpcy50O1xuICB9IGVsc2Uge1xuICAgIGYgPSB0aGlzLnMgJiB0aGlzLkRNO1xuICAgIGZvciAoaSA9IG07IGkgPCBhLnQ7ICsraSkgcltpXSA9IG9wKGYsIGFbaV0pO1xuICAgIHIudCA9IGEudDtcbiAgfVxuICByLnMgPSBvcCh0aGlzLnMsIGEucyk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIGFcblxuZnVuY3Rpb24gb3BfYW5kKHgsIHkpIHtcbiAgcmV0dXJuIHggJiB5O1xufVxuXG5mdW5jdGlvbiBibkFuZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX2FuZCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIHwgYVxuXG5mdW5jdGlvbiBvcF9vcih4LCB5KSB7XG4gIHJldHVybiB4IHwgeTtcbn1cblxuZnVuY3Rpb24gYm5PcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX29yLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiBhXG5cbmZ1bmN0aW9uIG9wX3hvcih4LCB5KSB7XG4gIHJldHVybiB4IF4geTtcbn1cblxuZnVuY3Rpb24gYm5Yb3IoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF94b3IsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH5hXG5cbmZ1bmN0aW9uIG9wX2FuZG5vdCh4LCB5KSB7XG4gIHJldHVybiB4ICYgfnk7XG59XG5cbmZ1bmN0aW9uIGJuQW5kTm90KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kbm90LCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIH50aGlzXG5cbmZ1bmN0aW9uIGJuTm90KCkge1xuICB2YXIgciA9IG5iaSgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSAmIH50aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IH50aGlzLnM7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIDw8IG5cblxuZnVuY3Rpb24gYm5TaGlmdExlZnQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZiAobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4sIHIpO1xuICBlbHNlIHRoaXMubFNoaWZ0VG8obiwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzID4+IG5cblxuZnVuY3Rpb24gYm5TaGlmdFJpZ2h0KG4pIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgaWYgKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLCByKTtcbiAgZWxzZSB0aGlzLnJTaGlmdFRvKG4sIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gcmV0dXJuIGluZGV4IG9mIGxvd2VzdCAxLWJpdCBpbiB4LCB4IDwgMl4zMVxuXG5mdW5jdGlvbiBsYml0KHgpIHtcbiAgaWYgKHggPT0gMCkgcmV0dXJuIC0xO1xuICB2YXIgciA9IDA7XG4gIGlmICgoeCAmIDB4ZmZmZikgPT0gMCkge1xuICAgIHggPj49IDE2O1xuICAgIHIgKz0gMTY7XG4gIH1cbiAgaWYgKCh4ICYgMHhmZikgPT0gMCkge1xuICAgIHggPj49IDg7XG4gICAgciArPSA4O1xuICB9XG4gIGlmICgoeCAmIDB4ZikgPT0gMCkge1xuICAgIHggPj49IDQ7XG4gICAgciArPSA0O1xuICB9XG4gIGlmICgoeCAmIDMpID09IDApIHtcbiAgICB4ID4+PSAyO1xuICAgIHIgKz0gMjtcbiAgfVxuICBpZiAoKHggJiAxKSA9PSAwKSsrcjtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKVxuXG5mdW5jdGlvbiBibkdldExvd2VzdFNldEJpdCgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSlcbiAgICBpZiAodGhpc1tpXSAhPSAwKSByZXR1cm4gaSAqIHRoaXMuREIgKyBsYml0KHRoaXNbaV0pO1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIHRoaXMudCAqIHRoaXMuREI7XG4gIHJldHVybiAtMTtcbn1cblxuLy8gcmV0dXJuIG51bWJlciBvZiAxIGJpdHMgaW4geFxuXG5mdW5jdGlvbiBjYml0KHgpIHtcbiAgdmFyIHIgPSAwO1xuICB3aGlsZSAoeCAhPSAwKSB7XG4gICAgeCAmPSB4IC0gMTtcbiAgICArK3I7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBudW1iZXIgb2Ygc2V0IGJpdHNcblxuZnVuY3Rpb24gYm5CaXRDb3VudCgpIHtcbiAgdmFyIHIgPSAwLFxuICAgIHggPSB0aGlzLnMgJiB0aGlzLkRNO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpc1tpXSBeIHgpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcblxuZnVuY3Rpb24gYm5UZXN0Qml0KG4pIHtcbiAgdmFyIGogPSBNYXRoLmZsb29yKG4gLyB0aGlzLkRCKTtcbiAgaWYgKGogPj0gdGhpcy50KSByZXR1cm4gKHRoaXMucyAhPSAwKTtcbiAgcmV0dXJuICgodGhpc1tqXSAmICgxIDw8IChuICUgdGhpcy5EQikpKSAhPSAwKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcblxuZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sIG9wKSB7XG4gIHZhciByID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KG4pO1xuICB0aGlzLmJpdHdpc2VUbyhyLCBvcCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIHwgKDE8PG4pXG5cbmZ1bmN0aW9uIGJuU2V0Qml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX29yKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH4oMTw8bilcblxuZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF9hbmRub3QpO1xufVxuXG4vLyAocHVibGljKSB0aGlzIF4gKDE8PG4pXG5cbmZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF94b3IpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyArIGFcblxuZnVuY3Rpb24gYm5wQWRkVG8oYSwgcikge1xuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgdGhpcy50KTtcbiAgd2hpbGUgKGkgPCBtKSB7XG4gICAgYyArPSB0aGlzW2ldICsgYVtpXTtcbiAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICBjID4+PSB0aGlzLkRCO1xuICB9XG4gIGlmIChhLnQgPCB0aGlzLnQpIHtcbiAgICBjICs9IGEucztcbiAgICB3aGlsZSAoaSA8IHRoaXMudCkge1xuICAgICAgYyArPSB0aGlzW2ldO1xuICAgICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgICBjID4+PSB0aGlzLkRCO1xuICAgIH1cbiAgICBjICs9IHRoaXMucztcbiAgfSBlbHNlIHtcbiAgICBjICs9IHRoaXMucztcbiAgICB3aGlsZSAoaSA8IGEudCkge1xuICAgICAgYyArPSBhW2ldO1xuICAgICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgICBjID4+PSB0aGlzLkRCO1xuICAgIH1cbiAgICBjICs9IGEucztcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwO1xuICBpZiAoYyA+IDApIHJbaSsrXSA9IGM7XG4gIGVsc2UgaWYgKGMgPCAtMSkgcltpKytdID0gdGhpcy5EViArIGM7XG4gIHIudCA9IGk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyArIGFcblxuZnVuY3Rpb24gYm5BZGQoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmFkZFRvKGEsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAtIGFcblxuZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuc3ViVG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICogYVxuXG5mdW5jdGlvbiBibk11bHRpcGx5KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5tdWx0aXBseVRvKGEsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpc14yXG5cbmZ1bmN0aW9uIGJuU3F1YXJlKCkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLnNxdWFyZVRvKHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAvIGFcblxuZnVuY3Rpb24gYm5EaXZpZGUoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmRpdlJlbVRvKGEsIHIsIG51bGwpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAlIGFcblxuZnVuY3Rpb24gYm5SZW1haW5kZXIoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmRpdlJlbVRvKGEsIG51bGwsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgW3RoaXMvYSx0aGlzJWFdXG5cbmZ1bmN0aW9uIGJuRGl2aWRlQW5kUmVtYWluZGVyKGEpIHtcbiAgdmFyIHEgPSBuYmkoKSxcbiAgICByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgcSwgcik7XG4gIHJldHVybiBuZXcgQXJyYXkocSwgcik7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKj0gbiwgdGhpcyA+PSAwLCAxIDwgbiA8IERWXG5cbmZ1bmN0aW9uIGJucERNdWx0aXBseShuKSB7XG4gIHRoaXNbdGhpcy50XSA9IHRoaXMuYW0oMCwgbiAtIDEsIHRoaXMsIDAsIDAsIHRoaXMudCk7XG4gICsrdGhpcy50O1xuICB0aGlzLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKz0gbiA8PCB3IHdvcmRzLCB0aGlzID49IDBcblxuZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLCB3KSB7XG4gIGlmIChuID09IDApIHJldHVybjtcbiAgd2hpbGUgKHRoaXMudCA8PSB3KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gIHRoaXNbd10gKz0gbjtcbiAgd2hpbGUgKHRoaXNbd10gPj0gdGhpcy5EVikge1xuICAgIHRoaXNbd10gLT0gdGhpcy5EVjtcbiAgICBpZiAoKyt3ID49IHRoaXMudCkgdGhpc1t0aGlzLnQrK10gPSAwO1xuICAgICsrdGhpc1t3XTtcbiAgfVxufVxuXG4vLyBBIFwibnVsbFwiIHJlZHVjZXJcblxuZnVuY3Rpb24gTnVsbEV4cCgpIHt9XG5cbmZ1bmN0aW9uIG5Ob3AoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gbk11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xufVxuXG5mdW5jdGlvbiBuU3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xufVxuXG5OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0ID0gbk5vcDtcbk51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3A7XG5OdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbztcbk51bGxFeHAucHJvdG90eXBlLnNxclRvID0gblNxclRvO1xuXG4vLyAocHVibGljKSB0aGlzXmVcblxuZnVuY3Rpb24gYm5Qb3coZSkge1xuICByZXR1cm4gdGhpcy5leHAoZSwgbmV3IE51bGxFeHAoKSk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsIG4sIHIpIHtcbiAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQgKyBhLnQsIG4pO1xuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHIudCA9IGk7XG4gIHdoaWxlIChpID4gMCkgclstLWldID0gMDtcbiAgdmFyIGo7XG4gIGZvciAoaiA9IHIudCAtIHRoaXMudDsgaSA8IGo7ICsraSkgcltpICsgdGhpcy50XSA9IHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgdGhpcy50KTtcbiAgZm9yIChqID0gTWF0aC5taW4oYS50LCBuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCBuIC0gaSk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLCBuLCByKSB7XG4gIC0tbjtcbiAgdmFyIGkgPSByLnQgPSB0aGlzLnQgKyBhLnQgLSBuO1xuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IE1hdGgubWF4KG4gLSB0aGlzLnQsIDApOyBpIDwgYS50OyArK2kpXG4gICAgclt0aGlzLnQgKyBpIC0gbl0gPSB0aGlzLmFtKG4gLSBpLCBhW2ldLCByLCAwLCAwLCB0aGlzLnQgKyBpIC0gbik7XG4gIHIuY2xhbXAoKTtcbiAgci5kclNoaWZ0VG8oMSwgcik7XG59XG5cbi8vIEJhcnJldHQgbW9kdWxhciByZWR1Y3Rpb25cblxuZnVuY3Rpb24gQmFycmV0dChtKSB7XG4gIC8vIHNldHVwIEJhcnJldHRcbiAgdGhpcy5yMiA9IG5iaSgpO1xuICB0aGlzLnEzID0gbmJpKCk7XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyICogbS50LCB0aGlzLnIyKTtcbiAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pO1xuICB0aGlzLm0gPSBtO1xufVxuXG5mdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHgudCA+IDIgKiB0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gIGVsc2UgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDtcbiAgZWxzZSB7XG4gICAgdmFyIHIgPSBuYmkoKTtcbiAgICB4LmNvcHlUbyhyKTtcbiAgICB0aGlzLnJlZHVjZShyKTtcbiAgICByZXR1cm4gcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHg7XG59XG5cbi8vIHggPSB4IG1vZCBtIChIQUMgMTQuNDIpXG5cbmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkge1xuICB4LmRyU2hpZnRUbyh0aGlzLm0udCAtIDEsIHRoaXMucjIpO1xuICBpZiAoeC50ID4gdGhpcy5tLnQgKyAxKSB7XG4gICAgeC50ID0gdGhpcy5tLnQgKyAxO1xuICAgIHguY2xhbXAoKTtcbiAgfVxuICB0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLCB0aGlzLm0udCArIDEsIHRoaXMucTMpO1xuICB0aGlzLm0ubXVsdGlwbHlMb3dlclRvKHRoaXMucTMsIHRoaXMubS50ICsgMSwgdGhpcy5yMik7XG4gIHdoaWxlICh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLCB0aGlzLm0udCArIDEpO1xuICB4LnN1YlRvKHRoaXMucjIsIHgpO1xuICB3aGlsZSAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeCk7XG59XG5cbi8vIHIgPSB4XjIgbW9kIG07IHggIT0gclxuXG5mdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuLy8gciA9IHgqeSBtb2QgbTsgeCx5ICE9IHJcblxuZnVuY3Rpb24gYmFycmV0dE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0O1xuQmFycmV0dC5wcm90b3R5cGUucmV2ZXJ0ID0gYmFycmV0dFJldmVydDtcbkJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2U7XG5CYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbztcbkJhcnJldHQucHJvdG90eXBlLnNxclRvID0gYmFycmV0dFNxclRvO1xuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG5cbmZ1bmN0aW9uIGJuTW9kUG93KGUsIG0pIHtcbiAgdmFyIGkgPSBlLmJpdExlbmd0aCgpLFxuICAgIGssIHIgPSBuYnYoMSksXG4gICAgejtcbiAgaWYgKGkgPD0gMCkgcmV0dXJuIHI7XG4gIGVsc2UgaWYgKGkgPCAxOCkgayA9IDE7XG4gIGVsc2UgaWYgKGkgPCA0OCkgayA9IDM7XG4gIGVsc2UgaWYgKGkgPCAxNDQpIGsgPSA0O1xuICBlbHNlIGlmIChpIDwgNzY4KSBrID0gNTtcbiAgZWxzZSBrID0gNjtcbiAgaWYgKGkgPCA4KVxuICAgIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgZWxzZSBpZiAobS5pc0V2ZW4oKSlcbiAgICB6ID0gbmV3IEJhcnJldHQobSk7XG4gIGVsc2VcbiAgICB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG5cbiAgLy8gcHJlY29tcHV0YXRpb25cbiAgdmFyIGcgPSBuZXcgQXJyYXkoKSxcbiAgICBuID0gMyxcbiAgICBrMSA9IGsgLSAxLFxuICAgIGttID0gKDEgPDwgaykgLSAxO1xuICBnWzFdID0gei5jb252ZXJ0KHRoaXMpO1xuICBpZiAoayA+IDEpIHtcbiAgICB2YXIgZzIgPSBuYmkoKTtcbiAgICB6LnNxclRvKGdbMV0sIGcyKTtcbiAgICB3aGlsZSAobiA8PSBrbSkge1xuICAgICAgZ1tuXSA9IG5iaSgpO1xuICAgICAgei5tdWxUbyhnMiwgZ1tuIC0gMl0sIGdbbl0pO1xuICAgICAgbiArPSAyO1xuICAgIH1cbiAgfVxuXG4gIHZhciBqID0gZS50IC0gMSxcbiAgICB3LCBpczEgPSB0cnVlLFxuICAgIHIyID0gbmJpKCksXG4gICAgdDtcbiAgaSA9IG5iaXRzKGVbal0pIC0gMTtcbiAgd2hpbGUgKGogPj0gMCkge1xuICAgIGlmIChpID49IGsxKSB3ID0gKGVbal0gPj4gKGkgLSBrMSkpICYga207XG4gICAgZWxzZSB7XG4gICAgICB3ID0gKGVbal0gJiAoKDEgPDwgKGkgKyAxKSkgLSAxKSkgPDwgKGsxIC0gaSk7XG4gICAgICBpZiAoaiA+IDApIHcgfD0gZVtqIC0gMV0gPj4gKHRoaXMuREIgKyBpIC0gazEpO1xuICAgIH1cblxuICAgIG4gPSBrO1xuICAgIHdoaWxlICgodyAmIDEpID09IDApIHtcbiAgICAgIHcgPj49IDE7XG4gICAgICAtLW47XG4gICAgfVxuICAgIGlmICgoaSAtPSBuKSA8IDApIHtcbiAgICAgIGkgKz0gdGhpcy5EQjtcbiAgICAgIC0tajtcbiAgICB9XG4gICAgaWYgKGlzMSkgeyAvLyByZXQgPT0gMSwgZG9uJ3QgYm90aGVyIHNxdWFyaW5nIG9yIG11bHRpcGx5aW5nIGl0XG4gICAgICBnW3ddLmNvcHlUbyhyKTtcbiAgICAgIGlzMSA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAobiA+IDEpIHtcbiAgICAgICAgei5zcXJUbyhyLCByMik7XG4gICAgICAgIHouc3FyVG8ocjIsIHIpO1xuICAgICAgICBuIC09IDI7XG4gICAgICB9XG4gICAgICBpZiAobiA+IDApIHouc3FyVG8ociwgcjIpO1xuICAgICAgZWxzZSB7XG4gICAgICAgIHQgPSByO1xuICAgICAgICByID0gcjI7XG4gICAgICAgIHIyID0gdDtcbiAgICAgIH1cbiAgICAgIHoubXVsVG8ocjIsIGdbd10sIHIpO1xuICAgIH1cblxuICAgIHdoaWxlIChqID49IDAgJiYgKGVbal0gJiAoMSA8PCBpKSkgPT0gMCkge1xuICAgICAgei5zcXJUbyhyLCByMik7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSByMjtcbiAgICAgIHIyID0gdDtcbiAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgIGkgPSB0aGlzLkRCIC0gMTtcbiAgICAgICAgLS1qO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocik7XG59XG5cbi8vIChwdWJsaWMpIGdjZCh0aGlzLGEpIChIQUMgMTQuNTQpXG5cbmZ1bmN0aW9uIGJuR0NEKGEpIHtcbiAgdmFyIHggPSAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcy5jbG9uZSgpO1xuICB2YXIgeSA9IChhLnMgPCAwKSA/IGEubmVnYXRlKCkgOiBhLmNsb25lKCk7XG4gIGlmICh4LmNvbXBhcmVUbyh5KSA8IDApIHtcbiAgICB2YXIgdCA9IHg7XG4gICAgeCA9IHk7XG4gICAgeSA9IHQ7XG4gIH1cbiAgdmFyIGkgPSB4LmdldExvd2VzdFNldEJpdCgpLFxuICAgIGcgPSB5LmdldExvd2VzdFNldEJpdCgpO1xuICBpZiAoZyA8IDApIHJldHVybiB4O1xuICBpZiAoaSA8IGcpIGcgPSBpO1xuICBpZiAoZyA+IDApIHtcbiAgICB4LnJTaGlmdFRvKGcsIHgpO1xuICAgIHkuclNoaWZ0VG8oZywgeSk7XG4gIH1cbiAgd2hpbGUgKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgaWYgKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGksIHgpO1xuICAgIGlmICgoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLCB5KTtcbiAgICBpZiAoeC5jb21wYXJlVG8oeSkgPj0gMCkge1xuICAgICAgeC5zdWJUbyh5LCB4KTtcbiAgICAgIHguclNoaWZ0VG8oMSwgeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkuc3ViVG8oeCwgeSk7XG4gICAgICB5LnJTaGlmdFRvKDEsIHkpO1xuICAgIH1cbiAgfVxuICBpZiAoZyA+IDApIHkubFNoaWZ0VG8oZywgeSk7XG4gIHJldHVybiB5O1xufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcblxuZnVuY3Rpb24gYm5wTW9kSW50KG4pIHtcbiAgaWYgKG4gPD0gMCkgcmV0dXJuIDA7XG4gIHZhciBkID0gdGhpcy5EViAlIG4sXG4gICAgciA9ICh0aGlzLnMgPCAwKSA/IG4gLSAxIDogMDtcbiAgaWYgKHRoaXMudCA+IDApXG4gICAgaWYgKGQgPT0gMCkgciA9IHRoaXNbMF0gJSBuO1xuICAgIGVsc2UgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByID0gKGQgKiByICsgdGhpc1tpXSkgJSBuO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgMS90aGlzICUgbSAoSEFDIDE0LjYxKVxuXG5mdW5jdGlvbiBibk1vZEludmVyc2UobSkge1xuICB2YXIgYWMgPSBtLmlzRXZlbigpO1xuICBpZiAoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgdmFyIHUgPSBtLmNsb25lKCksXG4gICAgdiA9IHRoaXMuY2xvbmUoKTtcbiAgdmFyIGEgPSBuYnYoMSksXG4gICAgYiA9IG5idigwKSxcbiAgICBjID0gbmJ2KDApLFxuICAgIGQgPSBuYnYoMSk7XG4gIHdoaWxlICh1LnNpZ251bSgpICE9IDApIHtcbiAgICB3aGlsZSAodS5pc0V2ZW4oKSkge1xuICAgICAgdS5yU2hpZnRUbygxLCB1KTtcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHtcbiAgICAgICAgICBhLmFkZFRvKHRoaXMsIGEpO1xuICAgICAgICAgIGIuc3ViVG8obSwgYik7XG4gICAgICAgIH1cbiAgICAgICAgYS5yU2hpZnRUbygxLCBhKTtcbiAgICAgIH0gZWxzZSBpZiAoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSwgYik7XG4gICAgICBiLnJTaGlmdFRvKDEsIGIpO1xuICAgIH1cbiAgICB3aGlsZSAodi5pc0V2ZW4oKSkge1xuICAgICAgdi5yU2hpZnRUbygxLCB2KTtcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHtcbiAgICAgICAgICBjLmFkZFRvKHRoaXMsIGMpO1xuICAgICAgICAgIGQuc3ViVG8obSwgZCk7XG4gICAgICAgIH1cbiAgICAgICAgYy5yU2hpZnRUbygxLCBjKTtcbiAgICAgIH0gZWxzZSBpZiAoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSwgZCk7XG4gICAgICBkLnJTaGlmdFRvKDEsIGQpO1xuICAgIH1cbiAgICBpZiAodS5jb21wYXJlVG8odikgPj0gMCkge1xuICAgICAgdS5zdWJUbyh2LCB1KTtcbiAgICAgIGlmIChhYykgYS5zdWJUbyhjLCBhKTtcbiAgICAgIGIuc3ViVG8oZCwgYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHYuc3ViVG8odSwgdik7XG4gICAgICBpZiAoYWMpIGMuc3ViVG8oYSwgYyk7XG4gICAgICBkLnN1YlRvKGIsIGQpO1xuICAgIH1cbiAgfVxuICBpZiAodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87XG4gIGlmIChkLmNvbXBhcmVUbyhtKSA+PSAwKSByZXR1cm4gZC5zdWJ0cmFjdChtKTtcbiAgaWYgKGQuc2lnbnVtKCkgPCAwKSBkLmFkZFRvKG0sIGQpO1xuICBlbHNlIHJldHVybiBkO1xuICBpZiAoZC5zaWdudW0oKSA8IDApIHJldHVybiBkLmFkZChtKTtcbiAgZWxzZSByZXR1cm4gZDtcbn1cblxudmFyIGxvd3ByaW1lcyA9IFsyLCAzLCA1LCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5LCAzMSwgMzcsIDQxLCA0MywgNDcsIDUzLCA1OSwgNjEsIDY3LCA3MSwgNzMsIDc5LCA4MywgODksIDk3LCAxMDEsXG4gICAgMTAzLCAxMDcsIDEwOSwgMTEzLCAxMjcsIDEzMSwgMTM3LCAxMzksIDE0OSwgMTUxLCAxNTcsIDE2MywgMTY3LCAxNzMsIDE3OSwgMTgxLCAxOTEsIDE5MywgMTk3LCAxOTksIDIxMSwgMjIzLCAyMjcsXG4gICAgMjI5LCAyMzMsIDIzOSwgMjQxLCAyNTEsIDI1NywgMjYzLCAyNjksIDI3MSwgMjc3LCAyODEsIDI4MywgMjkzLCAzMDcsIDMxMSwgMzEzLCAzMTcsIDMzMSwgMzM3LCAzNDcsIDM0OSwgMzUzLCAzNTksXG4gICAgMzY3LCAzNzMsIDM3OSwgMzgzLCAzODksIDM5NywgNDAxLCA0MDksIDQxOSwgNDIxLCA0MzEsIDQzMywgNDM5LCA0NDMsIDQ0OSwgNDU3LCA0NjEsIDQ2MywgNDY3LCA0NzksIDQ4NywgNDkxLCA0OTksXG4gICAgNTAzLCA1MDksIDUyMSwgNTIzLCA1NDEsIDU0NywgNTU3LCA1NjMsIDU2OSwgNTcxLCA1NzcsIDU4NywgNTkzLCA1OTksIDYwMSwgNjA3LCA2MTMsIDYxNywgNjE5LCA2MzEsIDY0MSwgNjQzLCA2NDcsXG4gICAgNjUzLCA2NTksIDY2MSwgNjczLCA2NzcsIDY4MywgNjkxLCA3MDEsIDcwOSwgNzE5LCA3MjcsIDczMywgNzM5LCA3NDMsIDc1MSwgNzU3LCA3NjEsIDc2OSwgNzczLCA3ODcsIDc5NywgODA5LCA4MTEsXG4gICAgODIxLCA4MjMsIDgyNywgODI5LCA4MzksIDg1MywgODU3LCA4NTksIDg2MywgODc3LCA4ODEsIDg4MywgODg3LCA5MDcsIDkxMSwgOTE5LCA5MjksIDkzNywgOTQxLCA5NDcsIDk1MywgOTY3LCA5NzEsXG4gICAgOTc3LCA5ODMsIDk5MSwgOTk3XG5dO1xudmFyIGxwbGltID0gKDEgPDwgMjYpIC8gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXTtcblxuLy8gKHB1YmxpYykgdGVzdCBwcmltYWxpdHkgd2l0aCBjZXJ0YWludHkgPj0gMS0uNV50XG5cbmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgdmFyIGksIHggPSB0aGlzLmFicygpO1xuICBpZiAoeC50ID09IDEgJiYgeFswXSA8PSBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGxvd3ByaW1lcy5sZW5ndGg7ICsraSlcbiAgICAgIGlmICh4WzBdID09IGxvd3ByaW1lc1tpXSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7XG4gIGkgPSAxO1xuICB3aGlsZSAoaSA8IGxvd3ByaW1lcy5sZW5ndGgpIHtcbiAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSxcbiAgICAgIGogPSBpICsgMTtcbiAgICB3aGlsZSAoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdO1xuICAgIG0gPSB4Lm1vZEludChtKTtcbiAgICB3aGlsZSAoaSA8IGopIGlmIChtICUgbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB4Lm1pbGxlclJhYmluKHQpO1xufVxuXG4vKiBhZGRlZCBieSBSZWN1cml0eSBMYWJzICovXG5cbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIG4gPSAxLFxuICAgIHQ7XG4gIGlmICgodCA9IHggPj4+IDE2KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSAxNjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDg7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSA0O1xuICB9XG4gIGlmICgodCA9IHggPj4gMikgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gMjtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDE7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbmZ1bmN0aW9uIGJuVG9NUEkoKSB7XG4gIHZhciBiYSA9IHRoaXMudG9CeXRlQXJyYXkoKTtcbiAgdmFyIHNpemUgPSAoYmEubGVuZ3RoIC0gMSkgKiA4ICsgbmJpdHMoYmFbMF0pO1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHNpemUgJiAweEZGMDApID4+IDgpO1xuICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShzaXplICYgMHhGRik7XG4gIHJlc3VsdCArPSB1dGlsLmJpbjJzdHIoYmEpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuLyogRU5EIG9mIGFkZGl0aW9uICovXG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG5mdW5jdGlvbiBibnBNaWxsZXJSYWJpbih0KSB7XG4gIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuICB2YXIgayA9IG4xLmdldExvd2VzdFNldEJpdCgpO1xuICBpZiAoayA8PSAwKSByZXR1cm4gZmFsc2U7XG4gIHZhciByID0gbjEuc2hpZnRSaWdodChrKTtcbiAgdCA9ICh0ICsgMSkgPj4gMTtcbiAgaWYgKHQgPiBsb3dwcmltZXMubGVuZ3RoKSB0ID0gbG93cHJpbWVzLmxlbmd0aDtcbiAgdmFyIGEgPSBuYmkoKTtcbiAgdmFyIGosIGJhc2VzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdDsgKytpKSB7XG4gICAgLy9QaWNrIGJhc2VzIGF0IHJhbmRvbSwgaW5zdGVhZCBvZiBzdGFydGluZyBhdCAyXG4gICAgZm9yICg7Oykge1xuICAgICAgaiA9IGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsb3dwcmltZXMubGVuZ3RoKV07XG4gICAgICBpZiAoYmFzZXMuaW5kZXhPZihqKSA9PSAtMSkgYnJlYWs7XG4gICAgfVxuICAgIGJhc2VzLnB1c2goaik7XG4gICAgYS5mcm9tSW50KGopO1xuICAgIHZhciB5ID0gYS5tb2RQb3cociwgdGhpcyk7XG4gICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICB2YXIgaiA9IDE7XG4gICAgICB3aGlsZSAoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICB5ID0geS5tb2RQb3dJbnQoMiwgdGhpcyk7XG4gICAgICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHkuY29tcGFyZVRvKG4xKSAhPSAwKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpO1xuXG4vLyBwcm90ZWN0ZWRcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXggPSBibnBUb1JhZGl4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVJhZGl4ID0gYm5wRnJvbVJhZGl4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG8gPSBibnBCaXR3aXNlVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jaGFuZ2VCaXQgPSBibnBDaGFuZ2VCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbyA9IGJucEFkZFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5ID0gYm5wRE11bHRpcGx5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZEFkZE9mZnNldCA9IGJucERBZGRPZmZzZXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG8gPSBibnBNdWx0aXBseVVwcGVyVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnQgPSBibnBNb2RJbnQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluO1xuXG4vLyBwdWJsaWNcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlID0gYm5JbnRWYWx1ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJ5dGVWYWx1ZSA9IGJuQnl0ZVZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bSA9IGJuU2lnTnVtO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9CeXRlQXJyYXkgPSBiblRvQnl0ZUFycmF5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5taW4gPSBibk1pbjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1heCA9IGJuTWF4O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5vciA9IGJuT3I7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS54b3IgPSBiblhvcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubm90ID0gYm5Ob3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdExlZnQgPSBiblNoaWZ0TGVmdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdENvdW50ID0gYm5CaXRDb3VudDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQgPSBiblNldEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNsZWFyQml0ID0gYm5DbGVhckJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQgPSBibkFkZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YnRyYWN0ID0gYm5TdWJ0cmFjdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZSA9IGJuRGl2aWRlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUucmVtYWluZGVyID0gYm5SZW1haW5kZXI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdyA9IGJuTW9kUG93O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW52ZXJzZSA9IGJuTW9kSW52ZXJzZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkID0gYm5HQ0Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pc1Byb2JhYmxlUHJpbWUgPSBibklzUHJvYmFibGVQcmltZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvTVBJID0gYm5Ub01QSTtcblxuLy8gSlNCTi1zcGVjaWZpYyBleHRlbnNpb25cbkJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZSA9IGJuU3F1YXJlO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBSU0EgaW1wbGVtZW50YXRpb25cblxuLyoqXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3B1YmxpY19rZXkvanNiblxuICogQHJlcXVpcmVzIGNyeXB0by9yYW5kb21cbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIGNyeXB0by9wdWJsaWNfa2V5L3JzYVxuICovXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyksXG4gIHJhbmRvbSA9IHJlcXVpcmUoJy4uL3JhbmRvbS5qcycpO1xuXG5mdW5jdGlvbiBTZWN1cmVSYW5kb20oKSB7XG4gIGZ1bmN0aW9uIG5leHRCeXRlcyhieXRlQXJyYXkpIHtcbiAgICBmb3IgKHZhciBuID0gMDsgbiA8IGJ5dGVBcnJheS5sZW5ndGg7IG4rKykge1xuICAgICAgYnl0ZUFycmF5W25dID0gcmFuZG9tLmdldFNlY3VyZVJhbmRvbU9jdGV0KCk7XG4gICAgfVxuICB9XG4gIHRoaXMubmV4dEJ5dGVzID0gbmV4dEJ5dGVzO1xufVxuXG5mdW5jdGlvbiBSU0EoKSB7XG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIHVzZXMganNibiBCaWcgTnVtIGxpYnJhcnkgdG8gZGVjcnlwdCBSU0FcbiAgICogQHBhcmFtIG1cbiAgICogICAgICAgICAgICBtZXNzYWdlXG4gICAqIEBwYXJhbSBkXG4gICAqICAgICAgICAgICAgUlNBIGQgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gcFxuICAgKiAgICAgICAgICAgIFJTQSBwIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIHFcbiAgICogICAgICAgICAgICBSU0EgcSBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSB1XG4gICAqICAgICAgICAgICAgUlNBIHUgYXMgQmlnSW50ZWdlclxuICAgKiBAcmV0dXJuIHtCaWdJbnRlZ2VyfSBUaGUgZGVjcnlwdGVkIHZhbHVlIG9mIHRoZSBtZXNzYWdlXG4gICAqL1xuICBmdW5jdGlvbiBkZWNyeXB0KG0sIGQsIHAsIHEsIHUpIHtcbiAgICB2YXIgeHAgPSBtLm1vZChwKS5tb2RQb3coZC5tb2QocC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpLCBwKTtcbiAgICB2YXIgeHEgPSBtLm1vZChxKS5tb2RQb3coZC5tb2QocS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpLCBxKTtcbiAgICB1dGlsLnByaW50X2RlYnVnKFwicnNhLmpzIGRlY3J5cHRcXG54cG46XCIgKyB1dGlsLmhleHN0cmR1bXAoeHAudG9NUEkoKSkgKyBcIlxcbnhxbjpcIiArIHV0aWwuaGV4c3RyZHVtcCh4cS50b01QSSgpKSk7XG5cbiAgICB2YXIgdCA9IHhxLnN1YnRyYWN0KHhwKTtcbiAgICBpZiAodFswXSA9PSAwKSB7XG4gICAgICB0ID0geHAuc3VidHJhY3QoeHEpO1xuICAgICAgdCA9IHQubXVsdGlwbHkodSkubW9kKHEpO1xuICAgICAgdCA9IHEuc3VidHJhY3QodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHQgPSB0Lm11bHRpcGx5KHUpLm1vZChxKTtcbiAgICB9XG4gICAgcmV0dXJuIHQubXVsdGlwbHkocCkuYWRkKHhwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBlbmNyeXB0IG1lc3NhZ2VcbiAgICogQHBhcmFtIG0gbWVzc2FnZSBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBlIHB1YmxpYyBNUEkgcGFydCBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBuIHB1YmxpYyBNUEkgcGFydCBhcyBCaWdJbnRlZ2VyXG4gICAqIEByZXR1cm4gQmlnSW50ZWdlclxuICAgKi9cbiAgZnVuY3Rpb24gZW5jcnlwdChtLCBlLCBuKSB7XG4gICAgcmV0dXJuIG0ubW9kUG93SW50KGUsIG4pO1xuICB9XG5cbiAgLyogU2lnbiBhbmQgVmVyaWZ5ICovXG4gIGZ1bmN0aW9uIHNpZ24obSwgZCwgbikge1xuICAgIHJldHVybiBtLm1vZFBvdyhkLCBuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZlcmlmeSh4LCBlLCBuKSB7XG4gICAgcmV0dXJuIHgubW9kUG93SW50KGUsIG4pO1xuICB9XG5cbiAgLy8gXCJlbXB0eVwiIFJTQSBrZXkgY29uc3RydWN0b3JcblxuICBmdW5jdGlvbiBrZXlPYmplY3QoKSB7XG4gICAgdGhpcy5uID0gbnVsbDtcbiAgICB0aGlzLmUgPSAwO1xuICAgIHRoaXMuZWUgPSBudWxsO1xuICAgIHRoaXMuZCA9IG51bGw7XG4gICAgdGhpcy5wID0gbnVsbDtcbiAgICB0aGlzLnEgPSBudWxsO1xuICAgIHRoaXMuZG1wMSA9IG51bGw7XG4gICAgdGhpcy5kbXExID0gbnVsbDtcbiAgICB0aGlzLnUgPSBudWxsO1xuICB9XG5cbiAgLy8gR2VuZXJhdGUgYSBuZXcgcmFuZG9tIHByaXZhdGUga2V5IEIgYml0cyBsb25nLCB1c2luZyBwdWJsaWMgZXhwdCBFXG5cbiAgZnVuY3Rpb24gZ2VuZXJhdGUoQiwgRSkge1xuICAgIHZhciBrZXkgPSBuZXcga2V5T2JqZWN0KCk7XG4gICAgdmFyIHJuZyA9IG5ldyBTZWN1cmVSYW5kb20oKTtcbiAgICB2YXIgcXMgPSBCID4+IDE7XG4gICAga2V5LmUgPSBwYXJzZUludChFLCAxNik7XG4gICAga2V5LmVlID0gbmV3IEJpZ0ludGVnZXIoRSwgMTYpO1xuICAgIGZvciAoOzspIHtcbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAga2V5LnAgPSBuZXcgQmlnSW50ZWdlcihCIC0gcXMsIDEsIHJuZyk7XG4gICAgICAgIGlmIChrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwICYmIGtleS5wLmlzUHJvYmFibGVQcmltZSgxMCkpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGtleS5xID0gbmV3IEJpZ0ludGVnZXIocXMsIDEsIHJuZyk7XG4gICAgICAgIGlmIChrZXkucS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwICYmIGtleS5xLmlzUHJvYmFibGVQcmltZSgxMCkpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoa2V5LnAuY29tcGFyZVRvKGtleS5xKSA8PSAwKSB7XG4gICAgICAgIHZhciB0ID0ga2V5LnA7XG4gICAgICAgIGtleS5wID0ga2V5LnE7XG4gICAgICAgIGtleS5xID0gdDtcbiAgICAgIH1cbiAgICAgIHZhciBwMSA9IGtleS5wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcbiAgICAgIHZhciBxMSA9IGtleS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcbiAgICAgIHZhciBwaGkgPSBwMS5tdWx0aXBseShxMSk7XG4gICAgICBpZiAocGhpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkge1xuICAgICAgICBrZXkubiA9IGtleS5wLm11bHRpcGx5KGtleS5xKTtcbiAgICAgICAga2V5LmQgPSBrZXkuZWUubW9kSW52ZXJzZShwaGkpO1xuICAgICAgICBrZXkuZG1wMSA9IGtleS5kLm1vZChwMSk7XG4gICAgICAgIGtleS5kbXExID0ga2V5LmQubW9kKHExKTtcbiAgICAgICAga2V5LnUgPSBrZXkucC5tb2RJbnZlcnNlKGtleS5xKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXk7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBlbmNyeXB0O1xuICB0aGlzLmRlY3J5cHQgPSBkZWNyeXB0O1xuICB0aGlzLnZlcmlmeSA9IHZlcmlmeTtcbiAgdGhpcy5zaWduID0gc2lnbjtcbiAgdGhpcy5nZW5lcmF0ZSA9IGdlbmVyYXRlO1xuICB0aGlzLmtleU9iamVjdCA9IGtleU9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSU0E7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQSBcblxuLy8gVGhlIEdQRzRCcm93c2VycyBjcnlwdG8gaW50ZXJmYWNlXG5cbi8qKlxuICogQHJlcXVpcmVzIHR5cGUvbXBpXG4gKiBAbW9kdWxlIGNyeXB0by9yYW5kb21cbiAqL1xuXG52YXIgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFJldHJpZXZlIHNlY3VyZSByYW5kb20gYnl0ZSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCBsZW5ndGhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIGluIGJ5dGVzIHRvIGdlbmVyYXRlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGUgc3RyaW5nXG4gICAqL1xuICBnZXRSYW5kb21CeXRlczogZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHBzZXVkby1yYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHBzZXVkbyByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRQc2V1ZG9SYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqICh0byAtIGZyb20pKSArIGZyb207XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHNlY3VyZSByYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHNlY3VyZSByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRTZWN1cmVSYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHZhciBiaXRzID0gKCh0byAtIGZyb20pKS50b1N0cmluZygyKS5sZW5ndGg7XG4gICAgd2hpbGUgKChidWZbMF0gJiAoTWF0aC5wb3coMiwgYml0cykgLSAxKSkgPiAodG8gLSBmcm9tKSlcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7XG4gICAgcmV0dXJuIGZyb20gKyAoTWF0aC5hYnMoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0gMSkpKTtcbiAgfSxcblxuICBnZXRTZWN1cmVSYW5kb21PY3RldDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBidWZbMF0gJiAweEZGO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzZWN1cmUgcmFuZG9tIGJpZyBpbnRlZ2VyIG9mIGJpdHMgbGVuZ3RoXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0cyBCaXQgbGVuZ3RoIG9mIHRoZSBNUEkgdG8gY3JlYXRlXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFJlc3VsdGluZyBiaWcgaW50ZWdlclxuICAgKi9cbiAgZ2V0UmFuZG9tQmlnSW50ZWdlcjogZnVuY3Rpb24oYml0cykge1xuICAgIGlmIChiaXRzIDwgMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMgKyA3KSAvIDgpO1xuXG4gICAgdmFyIHJhbmRvbUJpdHMgPSB0aGlzLmdldFJhbmRvbUJ5dGVzKG51bUJ5dGVzKTtcbiAgICBpZiAoYml0cyAlIDggPiAwKSB7XG5cbiAgICAgIHJhbmRvbUJpdHMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgKE1hdGgucG93KDIsIGJpdHMgJSA4KSAtIDEpICZcbiAgICAgICAgcmFuZG9tQml0cy5jaGFyQ29kZUF0KDApKSArXG4gICAgICAgIHJhbmRvbUJpdHMuc3Vic3RyaW5nKDEpO1xuICAgIH1cbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CeXRlcyhyYW5kb21CaXRzKTtcbiAgICByZXR1cm4gbXBpLnRvQmlnSW50ZWdlcigpO1xuICB9LFxuXG4gIGdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlOiBmdW5jdGlvbihtaW4sIG1heCkge1xuICAgIGlmIChtYXguY29tcGFyZVRvKG1pbikgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByYW5nZSA9IG1heC5zdWJ0cmFjdChtaW4pO1xuICAgIHZhciByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB3aGlsZSAociA+IHJhbmdlKSB7XG4gICAgICByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1pbi5hZGQocik7XG4gIH1cblxufTtcbiIsIi8qKlxuICogQHJlcXVpcmVzIGNyeXB0by9oYXNoXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3BrY3MxXG4gKiBAcmVxdWlyZXMgY3J5cHRvL3B1YmxpY19rZXlcbiAqIEBtb2R1bGUgY3J5cHRvL3NpZ25hdHVyZSAqL1xuXG52YXIgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHBrY3MxID0gcmVxdWlyZSgnLi9wa2NzMS5qcycpLFxuICBoYXNoTW9kdWxlID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBwdWJsaWMgS2V5IGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGhhc2hfYWxnbyBIYXNoIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IG1zZ19NUElzIFNpZ25hdHVyZSBtdWx0aXByZWNpc2lvbiBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0ge0FycmF5PG1vZHVsZTp0eXBlL21waT59IHB1YmxpY2tleV9NUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgb24gd2hlcmUgdGhlIHNpZ25hdHVyZSB3YXMgY29tcHV0ZWQgb24uXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgc2lnbmF0dXJlIChzaWdfZGF0YSB3YXMgZXF1YWwgdG8gZGF0YSBvdmVyIGhhc2gpXG4gICAqL1xuICB2ZXJpZnk6IGZ1bmN0aW9uKGFsZ28sIGhhc2hfYWxnbywgbXNnX01QSXMsIHB1YmxpY2tleV9NUElzLCBkYXRhKSB7XG4gICAgdmFyIGNhbGNfaGFzaCA9IGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hfYWxnbywgZGF0YSk7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgbiA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeCA9IG1zZ19NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZG9wdWJsaWMgPSByc2EudmVyaWZ5KHgsIGUsIG4pO1xuICAgICAgICB2YXIgaGFzaCA9IHBrY3MxLmVtc2EuZGVjb2RlKGhhc2hfYWxnbywgZG9wdWJsaWMudG9NUEkoKS5zdWJzdHJpbmcoMikpO1xuICAgICAgICBpZiAoaGFzaCA9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUzEgcGFkZGluZyBpbiBtZXNzYWdlIG9yIGtleSBpbmNvcnJlY3QuIEFib3J0aW5nLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc2ggPT0gY2FsY19oYXNoO1xuXG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC5cIik7XG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuICAgICAgICB2YXIgczEgPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIHMyID0gbXNnX01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBwID0gcHVibGlja2V5X01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0gcHVibGlja2V5X01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0gcHVibGlja2V5X01QSXNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0gcHVibGlja2V5X01QSXNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIGRvcHVibGljID0gZHNhLnZlcmlmeShoYXNoX2FsZ28sIHMxLCBzMiwgbSwgcCwgcSwgZywgeSk7XG4gICAgICAgIHJldHVybiBkb3B1YmxpYy5jb21wYXJlVG8oczEpID09IDA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGFsZ29yaXRobS4nKTtcbiAgICB9XG5cbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlIGEgc2lnbmF0dXJlIG9uIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoX2FsZ28gaGFzaCBBbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjEpXG4gICAqIEBwYXJhbSB7QXJyYXk8bW9kdWxlOnR5cGUvbXBpPn0gcHVibGljTVBJcyBQdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgXG4gICAqIEBwYXJhbSB7QXJyYXk8bW9kdWxlOnR5cGUvbXBpPn0gc2VjcmV0TVBJcyBQcml2YXRlIGtleSBtdWx0aXByZWNpc2lvbiBcbiAgICogaW50ZWdlcnMgd2hpY2ggaXMgdXNlZCB0byBzaWduIHRoZSBkYXRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgc2lnbmVkXG4gICAqIEByZXR1cm4ge0FycmF5PG1vZHVsZTp0eXBlL21waT59XG4gICAqL1xuICBzaWduOiBmdW5jdGlvbihoYXNoX2FsZ28sIGFsZ28sIGtleUludGVnZXJzLCBkYXRhKSB7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbiA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IHBrY3MxLmVtc2EuZW5jb2RlKGhhc2hfYWxnbyxcbiAgICAgICAgICBkYXRhLCBrZXlJbnRlZ2Vyc1swXS5ieXRlTGVuZ3RoKCkpO1xuXG4gICAgICAgIHJldHVybiByc2Euc2lnbihtLCBkLCBuKS50b01QSSgpO1xuXG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuXG4gICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0ga2V5SW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB4ID0ga2V5SW50ZWdlcnNbNF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRzYS5zaWduKGhhc2hfYWxnbywgbSwgZywgcCwgcSwgeCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFswXS50b1N0cmluZygpICsgcmVzdWx0WzFdLnRvU3RyaW5nKCk7XG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NpZ25pbmcgd2l0aCBFbGdhbWFsIGlzIG5vdCBkZWZpbmVkIGluIHRoZSBPcGVuUEdQIHN0YW5kYXJkLicpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEByZXF1aXJlcyBlbmNvZGluZy9iYXNlNjRcbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIGNvbmZpZ1xuICogQG1vZHVsZSBlbmNvZGluZy9hcm1vclxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCcuL2Jhc2U2NC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKipcbiAqIEZpbmRzIG91dCB3aGljaCBBc2NpaSBBcm1vcmluZyB0eXBlIGlzIHVzZWQuIFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFtTdHJpbmddIGFzY2lpIGFybW9yZWQgdGV4dFxuICogQHJldHVybnMge0ludGVnZXJ9IDAgPSBNRVNTQUdFIFBBUlQgbiBvZiBtXG4gKiAgICAgICAgIDEgPSBNRVNTQUdFIFBBUlQgblxuICogICAgICAgICAyID0gU0lHTkVEIE1FU1NBR0VcbiAqICAgICAgICAgMyA9IFBHUCBNRVNTQUdFXG4gKiAgICAgICAgIDQgPSBQVUJMSUMgS0VZIEJMT0NLXG4gKiAgICAgICAgIDUgPSBQUklWQVRFIEtFWSBCTE9DS1xuICogICAgICAgICBudWxsID0gdW5rbm93blxuICovXG5mdW5jdGlvbiBnZXRUeXBlKHRleHQpIHtcbiAgdmFyIHJlSGVhZGVyID0gL14tLS0tLShbXi1dKyktLS0tLSRcXG4vbTtcblxuICB2YXIgaGVhZGVyID0gdGV4dC5tYXRjaChyZUhlYWRlcik7XG5cbiAgLy8gQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgWC9ZXG4gIC8vIFVzZWQgZm9yIG11bHRpLXBhcnQgbWVzc2FnZXMsIHdoZXJlIHRoZSBhcm1vciBpcyBzcGxpdCBhbW9uZ3N0IFlcbiAgLy8gcGFydHMsIGFuZCB0aGlzIGlzIHRoZSBYdGggcGFydCBvdXQgb2YgWS5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkK1xcL1xcZCsvKSkge1xuICAgIHJldHVybiBlbnVtcy5hcm1vci5tdWx0aXBhcnRfc2VjdGlvbjtcbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFhcbiAgLy8gVXNlZCBmb3IgbXVsdGktcGFydCBtZXNzYWdlcywgd2hlcmUgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb2YgYW5cbiAgLy8gdW5zcGVjaWZpZWQgbnVtYmVyIG9mIHBhcnRzLiBSZXF1aXJlcyB0aGUgTUVTU0FHRS1JRCBBcm1vclxuICAvLyBIZWFkZXIgdG8gYmUgdXNlZC5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkKy8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLm11bHRpcGFydF9sYXN0O1xuXG4gIH0gZWxzZVxuICAvLyBCRUdJTiBQR1AgU0lHTkFUVVJFXG4gIC8vIFVzZWQgZm9yIGRldGFjaGVkIHNpZ25hdHVyZXMsIE9wZW5QR1AvTUlNRSBzaWduYXR1cmVzLCBhbmRcbiAgLy8gY2xlYXJ0ZXh0IHNpZ25hdHVyZXMuIE5vdGUgdGhhdCBQR1AgMi54IHVzZXMgQkVHSU4gUEdQIE1FU1NBR0VcbiAgLy8gZm9yIGRldGFjaGVkIHNpZ25hdHVyZXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBTSUdORUQgTUVTU0FHRS8pKSB7XG4gICAgcmV0dXJuIGVudW1zLmFybW9yLnNpZ25lZDtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIE1FU1NBR0VcbiAgLy8gVXNlZCBmb3Igc2lnbmVkLCBlbmNyeXB0ZWQsIG9yIGNvbXByZXNzZWQgZmlsZXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IubWVzc2FnZTtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0tcbiAgLy8gVXNlZCBmb3IgYXJtb3JpbmcgcHVibGljIGtleXMuXG4gIGlmIChoZWFkZXJbMV0ubWF0Y2goL0JFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IucHVibGljX2tleTtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLXG4gIC8vIFVzZWQgZm9yIGFybW9yaW5nIHByaXZhdGUga2V5cy5cbiAgaWYgKGhlYWRlclsxXS5tYXRjaCgvQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gZW51bXMuYXJtb3IucHJpdmF0ZV9rZXk7XG4gIH1cbn1cblxuLyoqXG4gKiBBZGQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0byB0aGUgYXJtb3IgdmVyc2lvbiBvZiBhbiBPcGVuUEdQIGJpbmFyeVxuICogcGFja2V0IGJsb2NrLlxuICogQGF1dGhvciAgQWxleFxuICogQHZlcnNpb24gMjAxMS0xMi0xNlxuICogQHJldHVybnMge1N0cmluZ30gVGhlIGhlYWRlciBpbmZvcm1hdGlvblxuICovXG5mdW5jdGlvbiBhZGRoZWFkZXIoKSB7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICBpZiAoY29uZmlnLnNob3dfdmVyc2lvbikge1xuICAgIHJlc3VsdCArPSBcIlZlcnNpb246IFwiICsgY29uZmlnLnZlcnNpb25zdHJpbmcgKyAnXFxyXFxuJztcbiAgfVxuICBpZiAoY29uZmlnLnNob3dfY29tbWVudCkge1xuICAgIHJlc3VsdCArPSBcIkNvbW1lbnQ6IFwiICsgY29uZmlnLmNvbW1lbnRzdHJpbmcgKyAnXFxyXFxuJztcbiAgfVxuICByZXN1bHQgKz0gJ1xcclxcbic7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgYSBjaGVja3N1bSBvdmVyIHRoZSBnaXZlbiBkYXRhIGFuZCByZXR1cm5zIGl0IGJhc2U2NCBlbmNvZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge1N0cmluZ30gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqL1xuZnVuY3Rpb24gZ2V0Q2hlY2tTdW0oZGF0YSkge1xuICB2YXIgYyA9IGNyZWF0ZWNyYzI0KGRhdGEpO1xuICB2YXIgc3RyID0gXCJcIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+PiAxNikgK1xuICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gOCkgJiAweEZGKSArXG4gICAgU3RyaW5nLmZyb21DaGFyQ29kZShjICYgMHhGRik7XG4gIHJldHVybiBiYXNlNjQuZW5jb2RlKHN0cik7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgY29tcGFyZXMgaXQgd2l0aCB0aGVcbiAqIGdpdmVuIGJhc2U2NCBlbmNvZGVkIGNoZWNrc3VtXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBjaGVja3N1bSBCYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2l2ZW4gY2hlY2tzdW0gaXMgY29ycmVjdDsgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIHZlcmlmeUNoZWNrU3VtKGRhdGEsIGNoZWNrc3VtKSB7XG4gIHZhciBjID0gZ2V0Q2hlY2tTdW0oZGF0YSk7XG4gIHZhciBkID0gY2hlY2tzdW07XG4gIHJldHVybiBjWzBdID09IGRbMF0gJiYgY1sxXSA9PSBkWzFdICYmIGNbMl0gPT0gZFsyXTtcbn1cbi8qKlxuICogSW50ZXJuYWwgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGEgQ1JDLTI0IGNoZWNrc3VtIG92ZXIgYSBnaXZlbiBzdHJpbmcgKGRhdGEpXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBDUkMtMjQgY2hlY2tzdW0gYXMgbnVtYmVyXG4gKi9cbnZhciBjcmNfdGFibGUgPSBbXG4gICAgMHgwMDAwMDAwMCwgMHgwMDg2NGNmYiwgMHgwMThhZDUwZCwgMHgwMTBjOTlmNiwgMHgwMzkzZTZlMSwgMHgwMzE1YWExYSwgMHgwMjE5MzNlYywgMHgwMjlmN2YxNywgMHgwN2ExODEzOSxcbiAgICAweDA3MjdjZGMyLCAweDA2MmI1NDM0LCAweDA2YWQxOGNmLCAweDA0MzI2N2Q4LCAweDA0YjQyYjIzLCAweDA1YjhiMmQ1LCAweDA1M2VmZTJlLCAweDBmYzU0ZTg5LCAweDBmNDMwMjcyLFxuICAgIDB4MGU0ZjliODQsIDB4MGVjOWQ3N2YsIDB4MGM1NmE4NjgsIDB4MGNkMGU0OTMsIDB4MGRkYzdkNjUsIDB4MGQ1YTMxOWUsIDB4MDg2NGNmYjAsIDB4MDhlMjgzNGIsIDB4MDllZTFhYmQsXG4gICAgMHgwOTY4NTY0NiwgMHgwYmY3Mjk1MSwgMHgwYjcxNjVhYSwgMHgwYTdkZmM1YywgMHgwYWZiYjBhNywgMHgxZjBjZDFlOSwgMHgxZjhhOWQxMiwgMHgxZTg2MDRlNCwgMHgxZTAwNDgxZixcbiAgICAweDFjOWYzNzA4LCAweDFjMTk3YmYzLCAweDFkMTVlMjA1LCAweDFkOTNhZWZlLCAweDE4YWQ1MGQwLCAweDE4MmIxYzJiLCAweDE5Mjc4NWRkLCAweDE5YTFjOTI2LCAweDFiM2ViNjMxLFxuICAgIDB4MWJiOGZhY2EsIDB4MWFiNDYzM2MsIDB4MWEzMjJmYzcsIDB4MTBjOTlmNjAsIDB4MTA0ZmQzOWIsIDB4MTE0MzRhNmQsIDB4MTFjNTA2OTYsIDB4MTM1YTc5ODEsIDB4MTNkYzM1N2EsXG4gICAgMHgxMmQwYWM4YywgMHgxMjU2ZTA3NywgMHgxNzY4MWU1OSwgMHgxN2VlNTJhMiwgMHgxNmUyY2I1NCwgMHgxNjY0ODdhZiwgMHgxNGZiZjhiOCwgMHgxNDdkYjQ0MywgMHgxNTcxMmRiNSxcbiAgICAweDE1Zjc2MTRlLCAweDNlMTlhM2QyLCAweDNlOWZlZjI5LCAweDNmOTM3NmRmLCAweDNmMTUzYTI0LCAweDNkOGE0NTMzLCAweDNkMGMwOWM4LCAweDNjMDA5MDNlLCAweDNjODZkY2M1LFxuICAgIDB4MzliODIyZWIsIDB4MzkzZTZlMTAsIDB4MzgzMmY3ZTYsIDB4MzhiNGJiMWQsIDB4M2EyYmM0MGEsIDB4M2FhZDg4ZjEsIDB4M2JhMTExMDcsIDB4M2IyNzVkZmMsIDB4MzFkY2VkNWIsXG4gICAgMHgzMTVhYTFhMCxcbiAgICAweDMwNTYzODU2LCAweDMwZDA3NGFkLCAweDMyNGYwYmJhLCAweDMyYzk0NzQxLCAweDMzYzVkZWI3LCAweDMzNDM5MjRjLCAweDM2N2Q2YzYyLCAweDM2ZmIyMDk5LCAweDM3ZjdiOTZmLFxuICAgIDB4Mzc3MWY1OTQsIDB4MzVlZThhODMsIDB4MzU2OGM2NzgsIDB4MzQ2NDVmOGUsIDB4MzRlMjEzNzUsIDB4MjExNTcyM2IsIDB4MjE5MzNlYzAsIDB4MjA5ZmE3MzYsIDB4MjAxOWViY2QsXG4gICAgMHgyMjg2OTRkYSwgMHgyMjAwZDgyMSwgMHgyMzBjNDFkNywgMHgyMzhhMGQyYywgMHgyNmI0ZjMwMiwgMHgyNjMyYmZmOSwgMHgyNzNlMjYwZiwgMHgyN2I4NmFmNCwgMHgyNTI3MTVlMyxcbiAgICAweDI1YTE1OTE4LCAweDI0YWRjMGVlLCAweDI0MmI4YzE1LCAweDJlZDAzY2IyLCAweDJlNTY3MDQ5LCAweDJmNWFlOWJmLCAweDJmZGNhNTQ0LCAweDJkNDNkYTUzLCAweDJkYzU5NmE4LFxuICAgIDB4MmNjOTBmNWUsIDB4MmM0ZjQzYTUsIDB4Mjk3MWJkOGIsIDB4MjlmN2YxNzAsIDB4MjhmYjY4ODYsIDB4Mjg3ZDI0N2QsIDB4MmFlMjViNmEsIDB4MmE2NDE3OTEsIDB4MmI2ODhlNjcsXG4gICAgMHgyYmVlYzI5YywgMHg3YzMzNDdhNCwgMHg3Y2I1MGI1ZiwgMHg3ZGI5OTJhOSwgMHg3ZDNmZGU1MiwgMHg3ZmEwYTE0NSwgMHg3ZjI2ZWRiZSwgMHg3ZTJhNzQ0OCwgMHg3ZWFjMzhiMyxcbiAgICAweDdiOTJjNjlkLCAweDdiMTQ4YTY2LCAweDdhMTgxMzkwLCAweDdhOWU1ZjZiLCAweDc4MDEyMDdjLCAweDc4ODc2Yzg3LCAweDc5OGJmNTcxLCAweDc5MGRiOThhLCAweDczZjYwOTJkLFxuICAgIDB4NzM3MDQ1ZDYsIDB4NzI3Y2RjMjAsIDB4NzJmYTkwZGIsIDB4NzA2NWVmY2MsIDB4NzBlM2EzMzcsIDB4NzFlZjNhYzEsIDB4NzE2OTc2M2EsIDB4NzQ1Nzg4MTQsIDB4NzRkMWM0ZWYsXG4gICAgMHg3NWRkNWQxOSwgMHg3NTViMTFlMiwgMHg3N2M0NmVmNSwgMHg3NzQyMjIwZSwgMHg3NjRlYmJmOCwgMHg3NmM4ZjcwMywgMHg2MzNmOTY0ZCwgMHg2M2I5ZGFiNiwgMHg2MmI1NDM0MCxcbiAgICAweDYyMzMwZmJiLFxuICAgIDB4NjBhYzcwYWMsIDB4NjAyYTNjNTcsIDB4NjEyNmE1YTEsIDB4NjFhMGU5NWEsIDB4NjQ5ZTE3NzQsIDB4NjQxODViOGYsIDB4NjUxNGMyNzksIDB4NjU5MjhlODIsIDB4NjcwZGYxOTUsXG4gICAgMHg2NzhiYmQ2ZSwgMHg2Njg3MjQ5OCwgMHg2NjAxNjg2MywgMHg2Y2ZhZDhjNCwgMHg2YzdjOTQzZiwgMHg2ZDcwMGRjOSwgMHg2ZGY2NDEzMiwgMHg2ZjY5M2UyNSwgMHg2ZmVmNzJkZSxcbiAgICAweDZlZTNlYjI4LCAweDZlNjVhN2QzLCAweDZiNWI1OWZkLCAweDZiZGQxNTA2LCAweDZhZDE4Y2YwLCAweDZhNTdjMDBiLCAweDY4YzhiZjFjLCAweDY4NGVmM2U3LCAweDY5NDI2YTExLFxuICAgIDB4NjljNDI2ZWEsIDB4NDIyYWU0NzYsIDB4NDJhY2E4OGQsIDB4NDNhMDMxN2IsIDB4NDMyNjdkODAsIDB4NDFiOTAyOTcsIDB4NDEzZjRlNmMsIDB4NDAzM2Q3OWEsIDB4NDBiNTliNjEsXG4gICAgMHg0NThiNjU0ZiwgMHg0NTBkMjliNCwgMHg0NDAxYjA0MiwgMHg0NDg3ZmNiOSwgMHg0NjE4ODNhZSwgMHg0NjllY2Y1NSwgMHg0NzkyNTZhMywgMHg0NzE0MWE1OCwgMHg0ZGVmYWFmZixcbiAgICAweDRkNjllNjA0LCAweDRjNjU3ZmYyLCAweDRjZTMzMzA5LCAweDRlN2M0YzFlLCAweDRlZmEwMGU1LCAweDRmZjY5OTEzLCAweDRmNzBkNWU4LCAweDRhNGUyYmM2LCAweDRhYzg2NzNkLFxuICAgIDB4NGJjNGZlY2IsIDB4NGI0MmIyMzAsIDB4NDlkZGNkMjcsIDB4NDk1YjgxZGMsIDB4NDg1NzE4MmEsIDB4NDhkMTU0ZDEsIDB4NWQyNjM1OWYsIDB4NWRhMDc5NjQsIDB4NWNhY2UwOTIsXG4gICAgMHg1YzJhYWM2OSwgMHg1ZWI1ZDM3ZSwgMHg1ZTMzOWY4NSwgMHg1ZjNmMDY3MywgMHg1ZmI5NGE4OCwgMHg1YTg3YjRhNiwgMHg1YTAxZjg1ZCwgMHg1YjBkNjFhYiwgMHg1YjhiMmQ1MCxcbiAgICAweDU5MTQ1MjQ3LCAweDU5OTIxZWJjLCAweDU4OWU4NzRhLCAweDU4MThjYmIxLCAweDUyZTM3YjE2LCAweDUyNjUzN2VkLCAweDUzNjlhZTFiLCAweDUzZWZlMmUwLCAweDUxNzA5ZGY3LFxuICAgIDB4NTFmNmQxMGMsXG4gICAgMHg1MGZhNDhmYSwgMHg1MDdjMDQwMSwgMHg1NTQyZmEyZiwgMHg1NWM0YjZkNCwgMHg1NGM4MmYyMiwgMHg1NDRlNjNkOSwgMHg1NmQxMWNjZSwgMHg1NjU3NTAzNSwgMHg1NzViYzljMyxcbiAgICAweDU3ZGQ4NTM4XG5dO1xuXG5mdW5jdGlvbiBjcmVhdGVjcmMyNChpbnB1dCkge1xuICB2YXIgY3JjID0gMHhCNzA0Q0U7XG4gIHZhciBpbmRleCA9IDA7XG5cbiAgd2hpbGUgKChpbnB1dC5sZW5ndGggLSBpbmRleCkgPiAxNikge1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMykpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgNykpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgOCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgOSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTApKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDExKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxMikpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTMpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDE0KSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxNSkpICYgMHhmZl07XG4gICAgaW5kZXggKz0gMTY7XG4gIH1cblxuICBmb3IgKHZhciBqID0gaW5kZXg7IGogPCBpbnB1dC5sZW5ndGg7IGorKykge1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsrKSkgJiAweGZmXTtcbiAgfVxuICByZXR1cm4gY3JjICYgMHhmZmZmZmY7XG59XG5cbi8qKlxuICogU3BsaXRzIGEgbWVzc2FnZSBpbnRvIHR3byBwYXJ0cywgdGhlIGhlYWRlcnMgYW5kIHRoZSBib2R5LiBUaGlzIGlzIGFuIGludGVybmFsIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZSBwYXJ0XG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3JcbiAqIG9yIGFuIG9iamVjdCB3aXRoIGF0dHJpYnV0ZSBcImhlYWRlcnNcIiBjb250YWluaW5nIHRoZSBoZWFkZXJzIGFuZFxuICogYW5kIGFuIGF0dHJpYnV0ZSBcImJvZHlcIiBjb250YWluaW5nIHRoZSBib2R5LlxuICovXG5mdW5jdGlvbiBzcGxpdEhlYWRlcnModGV4dCkge1xuICB2YXIgcmVFbXB0eUxpbmUgPSAvXltcXHQgXSpcXG4vbTtcbiAgdmFyIGhlYWRlcnMgPSBcIlwiO1xuICB2YXIgYm9keSA9IHRleHQ7XG5cbiAgdmFyIG1hdGNoUmVzdWx0ID0gcmVFbXB0eUxpbmUuZXhlYyh0ZXh0KTtcblxuICBpZiAobWF0Y2hSZXN1bHQgIT0gbnVsbCkge1xuICAgIGhlYWRlcnMgPSB0ZXh0LnNsaWNlKDAsIG1hdGNoUmVzdWx0LmluZGV4KTtcbiAgICBib2R5ID0gdGV4dC5zbGljZShtYXRjaFJlc3VsdC5pbmRleCArIG1hdGNoUmVzdWx0WzBdLmxlbmd0aCk7XG4gIH1cblxuICByZXR1cm4geyBoZWFkZXJzOiBoZWFkZXJzLCBib2R5OiBib2R5IH07XG59XG5cbi8qKlxuICogU3BsaXRzIGEgbWVzc2FnZSBpbnRvIHR3byBwYXJ0cywgdGhlIGJvZHkgYW5kIHRoZSBjaGVja3N1bS4gVGhpcyBpcyBhbiBpbnRlcm5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2UgcGFydFxuICogQHJldHVybnMgeyhCb29sZWFufE9iamVjdCl9IEVpdGhlciBmYWxzZSBpbiBjYXNlIG9mIGFuIGVycm9yXG4gKiBvciBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJib2R5XCIgY29udGFpbmluZyB0aGUgYm9keVxuICogYW5kIGFuIGF0dHJpYnV0ZSBcImNoZWNrc3VtXCIgY29udGFpbmluZyB0aGUgY2hlY2tzdW0uXG4gKi9cbmZ1bmN0aW9uIHNwbGl0Q2hlY2tzdW0odGV4dCkge1xuICB2YXIgcmVDaGVja3N1bVN0YXJ0ID0gL149L207XG4gIHZhciBib2R5ID0gdGV4dDtcbiAgdmFyIGNoZWNrc3VtID0gXCJcIjtcblxuICB2YXIgbWF0Y2hSZXN1bHQgPSByZUNoZWNrc3VtU3RhcnQuZXhlYyh0ZXh0KTtcblxuICBpZiAobWF0Y2hSZXN1bHQgIT0gbnVsbCkge1xuICAgIGJvZHkgPSB0ZXh0LnNsaWNlKDAsIG1hdGNoUmVzdWx0LmluZGV4KTtcbiAgICBjaGVja3N1bSA9IHRleHQuc2xpY2UobWF0Y2hSZXN1bHQuaW5kZXggKyAxKTtcbiAgfVxuXG4gIHJldHVybiB7IGJvZHk6IGJvZHksIGNoZWNrc3VtOiBjaGVja3N1bSB9O1xufVxuXG4vKipcbiAqIERlQXJtb3IgYW4gT3BlblBHUCBhcm1vcmVkIG1lc3NhZ2U7IHZlcmlmeSB0aGUgY2hlY2tzdW0gYW5kIHJldHVyblxuICogdGhlIGVuY29kZWQgYnl0ZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJ0ZXh0XCIgY29udGFpbmluZyB0aGUgbWVzc2FnZSB0ZXh0LFxuICogYW4gYXR0cmlidXRlIFwiZGF0YVwiIGNvbnRhaW5pbmcgdGhlIGJ5dGVzIGFuZCBcInR5cGVcIiBmb3IgdGhlIEFTQ0lJIGFybW9yIHR5cGVcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gZGVhcm1vcih0ZXh0KSB7XG4gIHZhciByZVNwbGl0ID0gL14tLS0tLVteLV0rLS0tLS0kXFxuL207XG5cbiAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKTtcblxuICB2YXIgdHlwZSA9IGdldFR5cGUodGV4dCk7XG4gIGlmICghdHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93IEFTQ0lJIGFybW9yIHR5cGUnKTtcbiAgfSBcblxuICB2YXIgc3BsaXR0ZXh0ID0gdGV4dC5zcGxpdChyZVNwbGl0KTtcblxuICAvLyBJRSBoYXMgYSBidWcgaW4gc3BsaXQgd2l0aCBhIHJlLiBJZiB0aGUgcGF0dGVybiBtYXRjaGVzIHRoZSBiZWdpbm5pbmcgb2YgdGhlXG4gIC8vIHN0cmluZyBpdCBkb2Vzbid0IGNyZWF0ZSBhbiBlbXB0eSBhcnJheSBlbGVtZW50IDAuIFNvIHdlIG5lZWQgdG8gZGV0ZWN0IHRoaXNcbiAgLy8gc28gd2Uga25vdyB0aGUgaW5kZXggb2YgdGhlIGRhdGEgd2UgYXJlIGludGVyZXN0ZWQgaW4uXG4gIHZhciBpbmRleEJhc2UgPSAxO1xuXG4gIHZhciByZXN1bHQsIGNoZWNrc3VtO1xuXG4gIGlmICh0ZXh0LnNlYXJjaChyZVNwbGl0KSAhPSBzcGxpdHRleHRbMF0ubGVuZ3RoKSB7XG4gICAgaW5kZXhCYXNlID0gMDtcbiAgfVxuXG4gIGlmICh0eXBlICE9IDIpIHtcbiAgICB2YXIgbXNnID0gc3BsaXRIZWFkZXJzKHNwbGl0dGV4dFtpbmRleEJhc2VdKTtcbiAgICB2YXIgbXNnX3N1bSA9IHNwbGl0Q2hlY2tzdW0obXNnLmJvZHkpO1xuXG4gICAgcmVzdWx0ID0ge1xuICAgICAgZGF0YTogYmFzZTY0LmRlY29kZShtc2dfc3VtLmJvZHkpLFxuICAgICAgdHlwZTogdHlwZVxuICAgIH07XG5cbiAgICBjaGVja3N1bSA9IG1zZ19zdW0uY2hlY2tzdW07XG4gIH0gZWxzZSB7XG4gICAgLy8gUmV2ZXJzZSBkYXNoLWVzY2FwaW5nIGZvciBtc2cgYW5kIHJlbW92ZSB0cmFpbGluZyB3aGl0ZXNwYWNlIGF0IGVuZCBvZiBsaW5lXG4gICAgdmFyIG1zZyA9IHNwbGl0SGVhZGVycyhzcGxpdHRleHRbaW5kZXhCYXNlXS5yZXBsYWNlKC9eLSAvbWcsICcnKS5yZXBsYWNlKC9bXFx0IF0rXFxuL2csIFwiXFxuXCIpKTtcbiAgICB2YXIgc2lnID0gc3BsaXRIZWFkZXJzKHNwbGl0dGV4dFtpbmRleEJhc2UgKyAxXS5yZXBsYWNlKC9eLSAvbWcsICcnKSk7XG4gICAgdmFyIHNpZ19zdW0gPSBzcGxpdENoZWNrc3VtKHNpZy5ib2R5KTtcblxuICAgIHJlc3VsdCA9IHtcbiAgICAgIHRleHQ6ICBtc2cuYm9keS5yZXBsYWNlKC9cXG4kLywgJycpLnJlcGxhY2UoL1xcbi9nLCBcIlxcclxcblwiKSxcbiAgICAgIGRhdGE6IGJhc2U2NC5kZWNvZGUoc2lnX3N1bS5ib2R5KSxcbiAgICAgIHR5cGU6IHR5cGVcbiAgICB9O1xuXG4gICAgY2hlY2tzdW0gPSBzaWdfc3VtLmNoZWNrc3VtO1xuICB9XG5cbiAgaWYgKCF2ZXJpZnlDaGVja1N1bShyZXN1bHQuZGF0YSwgY2hlY2tzdW0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXNjaWkgYXJtb3IgaW50ZWdyaXR5IGNoZWNrIG9uIG1lc3NhZ2UgZmFpbGVkOiAnXCJcbiAgICAgICsgY2hlY2tzdW1cbiAgICAgICsgXCInIHNob3VsZCBiZSAnXCJcbiAgICAgICsgZ2V0Q2hlY2tTdW0ocmVzdWx0KSArIFwiJ1wiKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cblxuLyoqXG4gKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2tcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxuICogQHBhcmFtIGJvZHlcbiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbFxuICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0XG4gKiBAc3RhdGljXG4gKi9cbmZ1bmN0aW9uIGFybW9yKG1lc3NhZ2V0eXBlLCBib2R5LCBwYXJ0aW5kZXgsIHBhcnR0b3RhbCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgc3dpdGNoIChtZXNzYWdldHlwZSkge1xuICAgIGNhc2UgZW51bXMuYXJtb3IubXVsdGlwYXJ0X3NlY3Rpb246XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5KTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGJvZHkpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCIvXCIgKyBwYXJ0dG90YWwgKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLm11dGxpcGFydF9sYXN0OlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBcIiArIHBhcnRpbmRleCArIFwiLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnNpZ25lZDpcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05FRCBNRVNTQUdFLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIkhhc2g6IFwiICsgYm9keS5oYXNoICsgXCJcXHJcXG5cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBib2R5LnRleHQucmVwbGFjZSgvXFxuLS9nLCBcIlxcbi0gLVwiKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShib2R5LmRhdGEpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keS5kYXRhKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZW51bXMuYXJtb3IubWVzc2FnZTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoYm9keSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShib2R5KSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIGVudW1zLmFybW9yLnB1YmxpY19rZXk6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcclxcblxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBlbnVtcy5hcm1vci5wcml2YXRlX2tleTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGJvZHkpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oYm9keSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGVuY29kZTogYXJtb3IsXG4gIGRlY29kZTogZGVhcm1vclxufTtcbiIsIi8qIE9wZW5QR1AgcmFkaXgtNjQvYmFzZTY0IHN0cmluZyBlbmNvZGluZy9kZWNvZGluZ1xuICogQ29weXJpZ2h0IDIwMDUgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAxLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIFxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3JcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XG4gKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgXG4gKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0XG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHNcbiAqIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi5cbiAqL1xuXG4vKipcbiAqIEBtb2R1bGUgZW5jb2RpbmcvYmFzZTY0XG4gKi9cblxudmFyIGI2NHMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cbi8qKlxuICogQ29udmVydCBiaW5hcnkgc3RyaW5nIHRvIHJhZGl4LTY0XG4gKiBAcGFyYW0ge1N0cmluZ30gdCBiaW5hcnkgc3RyaW5nIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHJhZGl4LTY0IHZlcnNpb24gb2YgaW5wdXQgc3RyaW5nXG4gKiBAc3RhdGljXG4gKi9cbmZ1bmN0aW9uIHMycih0KSB7XG4gIHZhciBhLCBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIGwgPSAwLFxuICAgIHMgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSB0LmNoYXJDb2RlQXQobik7XG4gICAgaWYgKHMgPT0gMCkge1xuICAgICAgciArPSBiNjRzLmNoYXJBdCgoYyA+PiAyKSAmIDYzKTtcbiAgICAgIGEgPSAoYyAmIDMpIDw8IDQ7XG4gICAgfSBlbHNlIGlmIChzID09IDEpIHtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoKGEgfCAoYyA+PiA0KSAmIDE1KSk7XG4gICAgICBhID0gKGMgJiAxNSkgPDwgMjtcbiAgICB9IGVsc2UgaWYgKHMgPT0gMikge1xuICAgICAgciArPSBiNjRzLmNoYXJBdChhIHwgKChjID4+IDYpICYgMykpO1xuICAgICAgbCArPSAxO1xuICAgICAgaWYgKChsICUgNjApID09IDApXG4gICAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoYyAmIDYzKTtcbiAgICB9XG4gICAgbCArPSAxO1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuXG4gICAgcyArPSAxO1xuICAgIGlmIChzID09IDMpXG4gICAgICBzID0gMDtcbiAgfVxuICBpZiAocyA+IDApIHtcbiAgICByICs9IGI2NHMuY2hhckF0KGEpO1xuICAgIGwgKz0gMTtcbiAgICBpZiAoKGwgJSA2MCkgPT0gMClcbiAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICByICs9ICc9JztcbiAgICBsICs9IDE7XG4gIH1cbiAgaWYgKHMgPT0gMSkge1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuICAgIHIgKz0gJz0nO1xuICB9XG5cbiAgcmV0dXJuIHI7XG59XG5cbi8qKlxuICogQ29udmVydCByYWRpeC02NCB0byBiaW5hcnkgc3RyaW5nXG4gKiBAcGFyYW0ge1N0cmluZ30gdCByYWRpeC02NCBzdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gYmluYXJ5IHZlcnNpb24gb2YgaW5wdXQgc3RyaW5nXG4gKiBAc3RhdGljXG4gKi9cbmZ1bmN0aW9uIHIycyh0KSB7XG4gIHZhciBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIHMgPSAwLFxuICAgIGEgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSBiNjRzLmluZGV4T2YodC5jaGFyQXQobikpO1xuICAgIGlmIChjID49IDApIHtcbiAgICAgIGlmIChzKVxuICAgICAgICByICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYSB8IChjID4+ICg2IC0gcykpICYgMjU1KTtcbiAgICAgIHMgPSAocyArIDIpICYgNztcbiAgICAgIGEgPSAoYyA8PCBzKSAmIDI1NTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmNvZGU6IHMycixcbiAgZGVjb2RlOiByMnNcbn1cbiIsIi8qKlxuICogQG1vZHVsZSBlbnVtc1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKiBBIHN0cmluZyB0byBrZXkgc3BlY2lmaWVyIHR5cGVcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgczJrOiB7XG4gICAgc2ltcGxlOiAwLFxuICAgIHNhbHRlZDogMSxcbiAgICBpdGVyYXRlZDogMyxcbiAgICBnbnU6IDEwMVxuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBwdWJsaWNLZXk6IHtcbiAgICByc2FfZW5jcnlwdF9zaWduOiAxLFxuICAgIHJzYV9lbmNyeXB0OiAyLFxuICAgIHJzYV9zaWduOiAzLFxuICAgIGVsZ2FtYWw6IDE2LFxuICAgIGRzYTogMTdcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjJcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgc3ltbWV0cmljOiB7XG4gICAgcGxhaW50ZXh0OiAwLFxuICAgIC8qKiBOb3QgaW1wbGVtZW50ZWQhICovXG4gICAgaWRlYTogMSxcbiAgICB0cmlwbGVkZXM6IDIsXG4gICAgY2FzdDU6IDMsXG4gICAgYmxvd2Zpc2g6IDQsXG4gICAgYWVzMTI4OiA3LFxuICAgIGFlczE5MjogOCxcbiAgICBhZXMyNTY6IDksXG4gICAgdHdvZmlzaDogMTBcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjNcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgY29tcHJlc3Npb246IHtcbiAgICB1bmNvbXByZXNzZWQ6IDAsXG4gICAgLyoqIFJGQzE5NTEgKi9cbiAgICB6aXA6IDEsXG4gICAgLyoqIFJGQzE5NTAgKi9cbiAgICB6bGliOiAyLFxuICAgIGJ6aXAyOiAzXG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS40XG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKiBAcmVhZG9ubHlcbiAgICovXG4gIGhhc2g6IHtcbiAgICBtZDU6IDEsXG4gICAgc2hhMTogMixcbiAgICByaXBlbWQ6IDMsXG4gICAgc2hhMjU2OiA4LFxuICAgIHNoYTM4NDogOSxcbiAgICBzaGE1MTI6IDEwLFxuICAgIHNoYTIyNDogMTFcbiAgfSxcblxuICAvKiogQSBsaXN0IG9mIHBhY2tldCB0eXBlcyBhbmQgbnVtZXJpYyB0YWdzIGFzc29jaWF0ZWQgd2l0aCB0aGVtLlxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBwYWNrZXQ6IHtcbiAgICBwdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMSxcbiAgICBzaWduYXR1cmU6IDIsXG4gICAgc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMyxcbiAgICBvbmVfcGFzc19zaWduYXR1cmU6IDQsXG4gICAgc2VjcmV0X2tleTogNSxcbiAgICBwdWJsaWNfa2V5OiA2LFxuICAgIHNlY3JldF9zdWJrZXk6IDcsXG4gICAgY29tcHJlc3NlZDogOCxcbiAgICBzeW1tZXRyaWNhbGx5X2VuY3J5cHRlZDogOSxcbiAgICBtYXJrZXI6IDEwLFxuICAgIGxpdGVyYWw6IDExLFxuICAgIHRydXN0OiAxMixcbiAgICB1c2VyaWQ6IDEzLFxuICAgIHB1YmxpY19zdWJrZXk6IDE0LFxuICAgIHVzZXJfYXR0cmlidXRlOiAxNyxcbiAgICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IDE4LFxuICAgIG1vZGlmaWNhdGlvbl9kZXRlY3Rpb25fY29kZTogMTlcbiAgfSxcblxuICAvKiogRGF0YSB0eXBlcyBpbiB0aGUgbGl0ZXJhbCBwYWNrZXRcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgbGl0ZXJhbDoge1xuICAgIC8qKiBCaW5hcnkgZGF0YSAnYicgKi9cbiAgICBiaW5hcnk6ICdiJy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFRleHQgZGF0YSAndCcgKi9cbiAgICB0ZXh0OiAndCcuY2hhckNvZGVBdCgpLFxuICAgIC8qKiBVdGY4IGRhdGEgJ3UnICovXG4gICAgdXRmODogJ3UnLmNoYXJDb2RlQXQoKVxuICB9LFxuXG5cbiAgLyoqIE9uZSBwYXNzIHNpZ25hdHVyZSBwYWNrZXQgdHlwZVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBzaWduYXR1cmU6IHtcbiAgICAvKiogMHgwMDogU2lnbmF0dXJlIG9mIGEgYmluYXJ5IGRvY3VtZW50LiAqL1xuICAgIGJpbmFyeTogMCxcbiAgICAvKiogMHgwMTogU2lnbmF0dXJlIG9mIGEgY2Fub25pY2FsIHRleHQgZG9jdW1lbnQuPGJyLz5cbiAgICAgKiBDYW5vbmljYWx5emluZyB0aGUgZG9jdW1lbnQgYnkgY29udmVydGluZyBsaW5lIGVuZGluZ3MuICovXG4gICAgdGV4dDogMSxcbiAgICAvKiogMHgwMjogU3RhbmRhbG9uZSBzaWduYXR1cmUuPGJyLz5cbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHNpZ25hdHVyZSBvZiBvbmx5IGl0cyBvd24gc3VicGFja2V0IGNvbnRlbnRzLlxuICAgICAqIEl0IGlzIGNhbGN1bGF0ZWQgaWRlbnRpY2FsbHkgdG8gYSBzaWduYXR1cmUgb3ZlciBhIHplcm8tbGVuZ2hcbiAgICAgKiBiaW5hcnkgZG9jdW1lbnQuICBOb3RlIHRoYXQgaXQgZG9lc24ndCBtYWtlIHNlbnNlIHRvIGhhdmUgYSBWM1xuICAgICAqIHN0YW5kYWxvbmUgc2lnbmF0dXJlLiAqL1xuICAgIHN0YW5kYWxvbmU6IDIsXG4gICAgLyoqIDB4MTA6IEdlbmVyaWMgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0Ljxici8+XG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gZG9lcyBub3QgbWFrZSBhbnkgcGFydGljdWxhclxuICAgICAqIGFzc2VydGlvbiBhcyB0byBob3cgd2VsbCB0aGUgY2VydGlmaWVyIGhhcyBjaGVja2VkIHRoYXQgdGhlIG93bmVyXG4gICAgICogb2YgdGhlIGtleSBpcyBpbiBmYWN0IHRoZSBwZXJzb24gZGVzY3JpYmVkIGJ5IHRoZSBVc2VyIElELiAqL1xuICAgIGNlcnRfZ2VuZXJpYzogMTYsXG4gICAgLyoqIDB4MTE6IFBlcnNvbmEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0Ljxici8+XG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIG5vdCBkb25lIGFueSB2ZXJpZmljYXRpb24gb2ZcbiAgICAgKiB0aGUgY2xhaW0gdGhhdCB0aGUgb3duZXIgb2YgdGhpcyBrZXkgaXMgdGhlIFVzZXIgSUQgc3BlY2lmaWVkLiAqL1xuICAgIGNlcnRfcGVyc29uYTogMTcsXG4gICAgLyoqIDB4MTI6IENhc3VhbCBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuPGJyLz5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgZG9uZSBzb21lIGNhc3VhbFxuICAgICAqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuICovXG4gICAgY2VydF9jYXN1YWw6IDE4LFxuICAgIC8qKiAweDEzOiBQb3NpdGl2ZSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuPGJyLz5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgZG9uZSBzdWJzdGFudGlhbFxuICAgICAqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuPGJyLz5cbiAgICAgKiA8YnIvPlxuICAgICAqIE1vc3QgT3BlblBHUCBpbXBsZW1lbnRhdGlvbnMgbWFrZSB0aGVpciBcImtleSBzaWduYXR1cmVzXCIgYXMgMHgxMFxuICAgICAqIGNlcnRpZmljYXRpb25zLiAgU29tZSBpbXBsZW1lbnRhdGlvbnMgY2FuIGlzc3VlIDB4MTEtMHgxM1xuICAgICAqIGNlcnRpZmljYXRpb25zLCBidXQgZmV3IGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgdHlwZXMuICovXG4gICAgY2VydF9wb3NpdGl2ZTogMTksXG4gICAgLyoqIDB4MzA6IENlcnRpZmljYXRpb24gcmV2b2NhdGlvbiBzaWduYXR1cmU8YnIvPlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIHJldm9rZXMgYW4gZWFybGllciBVc2VyIElEIGNlcnRpZmljYXRpb24gc2lnbmF0dXJlXG4gICAgICogKHNpZ25hdHVyZSBjbGFzcyAweDEwIHRocm91Z2ggMHgxMykgb3IgZGlyZWN0LWtleSBzaWduYXR1cmVcbiAgICAgKiAoMHgxRikuICBJdCBzaG91bGQgYmUgaXNzdWVkIGJ5IHRoZSBzYW1lIGtleSB0aGF0IGlzc3VlZCB0aGVcbiAgICAgKiByZXZva2VkIHNpZ25hdHVyZSBvciBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LiAgVGhlIHNpZ25hdHVyZVxuICAgICAqIGlzIGNvbXB1dGVkIG92ZXIgdGhlIHNhbWUgZGF0YSBhcyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpdFxuICAgICAqIHJldm9rZXMsIGFuZCBzaG91bGQgaGF2ZSBhIGxhdGVyIGNyZWF0aW9uIGRhdGUgdGhhbiB0aGF0XG4gICAgICogY2VydGlmaWNhdGUuICovXG4gICAgY2VydF9yZXZvY2F0aW9uOiA0OCxcbiAgICAvKiogMHgxODogU3Via2V5IEJpbmRpbmcgU2lnbmF0dXJlPGJyLz5cbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSB0aGUgdG9wLWxldmVsIHNpZ25pbmcga2V5IHRoYXRcbiAgICAgKiBpbmRpY2F0ZXMgdGhhdCBpdCBvd25zIHRoZSBzdWJrZXkuICBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkXG4gICAgICogZGlyZWN0bHkgb24gdGhlIHByaW1hcnkga2V5IGFuZCBzdWJrZXksIGFuZCBub3Qgb24gYW55IFVzZXIgSUQgb3JcbiAgICAgKiBvdGhlciBwYWNrZXRzLiAgQSBzaWduYXR1cmUgdGhhdCBiaW5kcyBhIHNpZ25pbmcgc3Via2V5IE1VU1QgaGF2ZVxuICAgICAqIGFuIEVtYmVkZGVkIFNpZ25hdHVyZSBzdWJwYWNrZXQgaW4gdGhpcyBiaW5kaW5nIHNpZ25hdHVyZSB0aGF0XG4gICAgICogY29udGFpbnMgYSAweDE5IHNpZ25hdHVyZSBtYWRlIGJ5IHRoZSBzaWduaW5nIHN1YmtleSBvbiB0aGVcbiAgICAgKiBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAqL1xuICAgIHN1YmtleV9iaW5kaW5nOiAyNCxcbiAgICAvKiogMHgxOTogUHJpbWFyeSBLZXkgQmluZGluZyBTaWduYXR1cmU8YnIvPlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc3RhdGVtZW50IGJ5IGEgc2lnbmluZyBzdWJrZXksIGluZGljYXRpbmdcbiAgICAgKiB0aGF0IGl0IGlzIG93bmVkIGJ5IHRoZSBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAgVGhpcyBzaWduYXR1cmVcbiAgICAgKiBpcyBjYWxjdWxhdGVkIHRoZSBzYW1lIHdheSBhcyBhIDB4MTggc2lnbmF0dXJlOiBkaXJlY3RseSBvbiB0aGVcbiAgICAgKiBwcmltYXJ5IGtleSBhbmQgc3Via2V5LCBhbmQgbm90IG9uIGFueSBVc2VyIElEIG9yIG90aGVyIHBhY2tldHMuPGJyLz5cbiAgICAgKiA8YnIvPlxuICAgICAqIFdoZW4gYSBzaWduYXR1cmUgaXMgbWFkZSBvdmVyIGEga2V5LCB0aGUgaGFzaCBkYXRhIHN0YXJ0cyB3aXRoIHRoZVxuICAgICAqIG9jdGV0IDB4OTksIGZvbGxvd2VkIGJ5IGEgdHdvLW9jdGV0IGxlbmd0aCBvZiB0aGUga2V5LCBhbmQgdGhlbiBib2R5XG4gICAgICogb2YgdGhlIGtleSBwYWNrZXQuICAoTm90ZSB0aGF0IHRoaXMgaXMgYW4gb2xkLXN0eWxlIHBhY2tldCBoZWFkZXIgZm9yXG4gICAgICogYSBrZXkgcGFja2V0IHdpdGggdHdvLW9jdGV0IGxlbmd0aC4pICBBIHN1YmtleSBiaW5kaW5nIHNpZ25hdHVyZVxuICAgICAqICh0eXBlIDB4MTgpIG9yIHByaW1hcnkga2V5IGJpbmRpbmcgc2lnbmF0dXJlICh0eXBlIDB4MTkpIHRoZW4gaGFzaGVzXG4gICAgICogdGhlIHN1YmtleSB1c2luZyB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG1haW4ga2V5IChhbHNvIHVzaW5nIDB4OTkgYXNcbiAgICAgKiB0aGUgZmlyc3Qgb2N0ZXQpLiAqL1xuICAgIGtleV9iaW5kaW5nOiAyNSxcbiAgICAvKiogMHgxRjogU2lnbmF0dXJlIGRpcmVjdGx5IG9uIGEga2V5PGJyLz5cbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIGEga2V5LiAgSXQgYmluZHMgdGhlXG4gICAgICogaW5mb3JtYXRpb24gaW4gdGhlIFNpZ25hdHVyZSBzdWJwYWNrZXRzIHRvIHRoZSBrZXksIGFuZCBpc1xuICAgICAqIGFwcHJvcHJpYXRlIHRvIGJlIHVzZWQgZm9yIHN1YnBhY2tldHMgdGhhdCBwcm92aWRlIGluZm9ybWF0aW9uXG4gICAgICogYWJvdXQgdGhlIGtleSwgc3VjaCBhcyB0aGUgUmV2b2NhdGlvbiBLZXkgc3VicGFja2V0LiAgSXQgaXMgYWxzb1xuICAgICAqIGFwcHJvcHJpYXRlIGZvciBzdGF0ZW1lbnRzIHRoYXQgbm9uLXNlbGYgY2VydGlmaWVycyB3YW50IHRvIG1ha2VcbiAgICAgKiBhYm91dCB0aGUga2V5IGl0c2VsZiwgcmF0aGVyIHRoYW4gdGhlIGJpbmRpbmcgYmV0d2VlbiBhIGtleSBhbmQgYVxuICAgICAqIG5hbWUuICovXG4gICAga2V5OiAzMSxcbiAgICAvKiogMHgyMDogS2V5IHJldm9jYXRpb24gc2lnbmF0dXJlPGJyLz5cbiAgICAgKiBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIGtleSBiZWluZyByZXZva2VkLiAgQVxuICAgICAqIHJldm9rZWQga2V5IGlzIG5vdCB0byBiZSB1c2VkLiAgT25seSByZXZvY2F0aW9uIHNpZ25hdHVyZXMgYnkgdGhlXG4gICAgICoga2V5IGJlaW5nIHJldm9rZWQsIG9yIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZVxuICAgICAqIGNvbnNpZGVyZWQgdmFsaWQgcmV2b2NhdGlvbiBzaWduYXR1cmVzLmEgKi9cbiAgICBrZXlfcmV2b2NhdGlvbjogMzIsXG4gICAgLyoqIDB4Mjg6IFN1YmtleSByZXZvY2F0aW9uIHNpZ25hdHVyZTxici8+XG4gICAgICogVGhlIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIHRoZSBzdWJrZXkgYmVpbmcgcmV2b2tlZC5cbiAgICAgKiBBIHJldm9rZWQgc3Via2V5IGlzIG5vdCB0byBiZSB1c2VkLiAgT25seSByZXZvY2F0aW9uIHNpZ25hdHVyZXNcbiAgICAgKiBieSB0aGUgdG9wLWxldmVsIHNpZ25hdHVyZSBrZXkgdGhhdCBpcyBib3VuZCB0byB0aGlzIHN1YmtleSwgb3JcbiAgICAgKiBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmUgY29uc2lkZXJlZCB2YWxpZFxuICAgICAqIHJldm9jYXRpb24gc2lnbmF0dXJlcy48YnIvPlxuICAgICAqIDxici8+XG4gICAgICogS2V5IHJldm9jYXRpb24gc2lnbmF0dXJlcyAodHlwZXMgMHgyMCBhbmQgMHgyOClcbiAgICAgKiBoYXNoIG9ubHkgdGhlIGtleSBiZWluZyByZXZva2VkLiAqL1xuICAgIHN1YmtleV9yZXZvY2F0aW9uOiA0MCxcbiAgICAvKiogMHg0MDogVGltZXN0YW1wIHNpZ25hdHVyZS48YnIvPlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIG9ubHkgbWVhbmluZ2Z1bCBmb3IgdGhlIHRpbWVzdGFtcCBjb250YWluZWQgaW5cbiAgICAgKiBpdC4gKi9cbiAgICB0aW1lc3RhbXA6IDY0LFxuICAgIC8qKiAweDUwOiBUaGlyZC1QYXJ0eSBDb25maXJtYXRpb24gc2lnbmF0dXJlLjxici8+XG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgYSBzaWduYXR1cmUgb3ZlciBzb21lIG90aGVyIE9wZW5QR1AgU2lnbmF0dXJlXG4gICAgICogcGFja2V0KHMpLiAgSXQgaXMgYW5hbG9nb3VzIHRvIGEgbm90YXJ5IHNlYWwgb24gdGhlIHNpZ25lZCBkYXRhLlxuICAgICAqIEEgdGhpcmQtcGFydHkgc2lnbmF0dXJlIFNIT1VMRCBpbmNsdWRlIFNpZ25hdHVyZSBUYXJnZXRcbiAgICAgKiBzdWJwYWNrZXQocykgdG8gZ2l2ZSBlYXN5IGlkZW50aWZpY2F0aW9uLiAgTm90ZSB0aGF0IHdlIHJlYWxseSBkb1xuICAgICAqIG1lYW4gU0hPVUxELiAgVGhlcmUgYXJlIHBsYXVzaWJsZSB1c2VzIGZvciB0aGlzIChzdWNoIGFzIGEgYmxpbmRcbiAgICAgKiBwYXJ0eSB0aGF0IG9ubHkgc2VlcyB0aGUgc2lnbmF0dXJlLCBub3QgdGhlIGtleSBvciBzb3VyY2VcbiAgICAgKiBkb2N1bWVudCkgdGhhdCBjYW5ub3QgaW5jbHVkZSBhIHRhcmdldCBzdWJwYWNrZXQuICovXG4gICAgdGhpcmRfcGFydHk6IDgwXG4gIH0sXG5cbiAgLyoqIFNpZ25hdHVyZSBzdWJwYWNrZXQgdHlwZVxuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBzaWduYXR1cmVTdWJwYWNrZXQ6IHtcbiAgICBzaWduYXR1cmVfY3JlYXRpb25fdGltZTogMixcbiAgICBzaWduYXR1cmVfZXhwaXJhdGlvbl90aW1lOiAzLFxuICAgIGV4cG9ydGFibGVfY2VydGlmaWNhdGlvbjogNCxcbiAgICB0cnVzdF9zaWduYXR1cmU6IDUsXG4gICAgcmVndWxhcl9leHByZXNzaW9uOiA2LFxuICAgIHJldm9jYWJsZTogNyxcbiAgICBrZXlfZXhwaXJhdGlvbl90aW1lOiA5LFxuICAgIHBsYWNlaG9sZGVyX2JhY2t3YXJkc19jb21wYXRpYmlsaXR5OiAxMCxcbiAgICBwcmVmZXJyZWRfc3ltbWV0cmljX2FsZ29yaXRobXM6IDExLFxuICAgIHJldm9jYXRpb25fa2V5OiAxMixcbiAgICBpc3N1ZXI6IDE2LFxuICAgIG5vdGF0aW9uX2RhdGE6IDIwLFxuICAgIHByZWZlcnJlZF9oYXNoX2FsZ29yaXRobXM6IDIxLFxuICAgIHByZWZlcnJlZF9jb21wcmVzc2lvbl9hbGdvcml0aG1zOiAyMixcbiAgICBrZXlfc2VydmVyX3ByZWZlcmVuY2VzOiAyMyxcbiAgICBwcmVmZXJyZWRfa2V5X3NlcnZlcjogMjQsXG4gICAgcHJpbWFyeV91c2VyX2lkOiAyNSxcbiAgICBwb2xpY3lfdXJpOiAyNixcbiAgICBrZXlfZmxhZ3M6IDI3LFxuICAgIHNpZ25lcnNfdXNlcl9pZDogMjgsXG4gICAgcmVhc29uX2Zvcl9yZXZvY2F0aW9uOiAyOSxcbiAgICBmZWF0dXJlczogMzAsXG4gICAgc2lnbmF0dXJlX3RhcmdldDogMzEsXG4gICAgZW1iZWRkZWRfc2lnbmF0dXJlOiAzMlxuICB9LFxuXG4gIC8qKiBLZXkgZmxhZ3NcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAga2V5RmxhZ3M6IHtcbiAgICAvKiogMHgwMSAtIFRoaXMga2V5IG1heSBiZSB1c2VkIHRvIGNlcnRpZnkgb3RoZXIga2V5cy4gKi9cbiAgICBjZXJ0aWZ5X2tleXM6IDEsXG4gICAgLyoqIDB4MDIgLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBzaWduIGRhdGEuICovXG4gICAgc2lnbl9kYXRhOiAyLFxuICAgIC8qKiAweDA0IC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgdG8gZW5jcnlwdCBjb21tdW5pY2F0aW9ucy4gKi9cbiAgICBlbmNyeXB0X2NvbW11bmljYXRpb246IDQsXG4gICAgLyoqIDB4MDggLSBUaGlzIGtleSBtYXkgYmUgdXNlZCB0byBlbmNyeXB0IHN0b3JhZ2UuICovXG4gICAgZW5jcnlwdF9zdG9yYWdlOiA4LFxuICAgIC8qKiAweDEwIC0gVGhlIHByaXZhdGUgY29tcG9uZW50IG9mIHRoaXMga2V5IG1heSBoYXZlIGJlZW4gc3BsaXRcbiAgICAgKiAgICAgICAgYnkgYSBzZWNyZXQtc2hhcmluZyBtZWNoYW5pc20uICovXG4gICAgc3BsaXRfcHJpdmF0ZV9rZXk6IDE2LFxuICAgIC8qKiAweDIwIC0gVGhpcyBrZXkgbWF5IGJlIHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uLiAqL1xuICAgIGF1dGhlbnRpY2F0aW9uOiAzMixcbiAgICAvKiogMHg4MCAtIFRoZSBwcml2YXRlIGNvbXBvbmVudCBvZiB0aGlzIGtleSBtYXkgYmUgaW4gdGhlXG4gICAgICogICAgICAgIHBvc3Nlc3Npb24gb2YgbW9yZSB0aGFuIG9uZSBwZXJzb24uICovXG4gICAgc2hhcmVkX3ByaXZhdGVfa2V5OiAxMjhcbiAgfSxcblxuICAvKiogS2V5IHN0YXR1c1xuICAgKiBAZW51bSB7SW50ZWdlcn1cbiAgICogQHJlYWRvbmx5XG4gICAqL1xuICBrZXlTdGF0dXM6IHtcbiAgICBpbnZhbGlkOiAgICAgIDAsXG4gICAgZXhwaXJlZDogICAgICAxLFxuICAgIHJldm9rZWQ6ICAgICAgMixcbiAgICB2YWxpZDogICAgICAgIDMsXG4gICAgbm9fc2VsZl9jZXJ0OiA0XG4gIH0sXG5cbiAgLyoqIEFybW9yIHR5cGVcbiAgICogQGVudW0ge0ludGVnZXJ9XG4gICAqIEByZWFkb25seVxuICAgKi9cbiAgYXJtb3I6IHtcbiAgICBtdWx0aXBhcnRfc2VjdGlvbjogMCxcbiAgICBtdWx0aXBhcnRfbGFzdDogMSxcbiAgICBzaWduZWQ6IDIsXG4gICAgbWVzc2FnZTogMyxcbiAgICBwdWJsaWNfa2V5OiA0LFxuICAgIHByaXZhdGVfa2V5OiA1XG4gIH0sXG5cbiAgLyoqIEFzc2VydHMgdmFsaWRpdHkgYW5kIGNvbnZlcnRzIGZyb20gc3RyaW5nL2ludGVnZXIgdG8gaW50ZWdlci4gKi9cbiAgd3JpdGU6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBpZiAodHlwZW9mIGUgPT0gJ251bWJlcicpIHtcbiAgICAgIGUgPSB0aGlzLnJlYWQodHlwZSwgZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVbZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHR5cGVbZV07XG4gICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuICB9LFxuICAvKiogQ29udmVydHMgZnJvbSBhbiBpbnRlZ2VyIHRvIHN0cmluZy4gKi9cbiAgcmVhZDogZnVuY3Rpb24odHlwZSwgZSkge1xuICAgIGZvciAodmFyIGkgaW4gdHlwZSlcbiAgICAgIGlmICh0eXBlW2ldID09IGUpIHJldHVybiBpO1xuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVudW0gdmFsdWUuJyk7XG4gIH1cbn1cbiIsIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL29wZW5wZ3AuanMnKTtcblxubW9kdWxlLmV4cG9ydHMua2V5ID0gcmVxdWlyZSgnLi9rZXkuanMnKTtcbm1vZHVsZS5leHBvcnRzLm1lc3NhZ2UgPSByZXF1aXJlKCcuL21lc3NhZ2UuanMnKTtcbm1vZHVsZS5leHBvcnRzLmNsZWFydGV4dCA9IHJlcXVpcmUoJy4vY2xlYXJ0ZXh0LmpzJyk7XG4vKipcbiAqIEBzZWUgbW9kdWxlOnV0aWwvdXRpbFxuICogQG1vZHVsZSB1dGlsXG4gKi9cbm1vZHVsZS5leHBvcnRzLnV0aWwgPSByZXF1aXJlKCcuL3V0aWwvdXRpbC5qcycpO1xubW9kdWxlLmV4cG9ydHMucGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbi8qKlxuICogQHNlZSBtb2R1bGU6dHlwZS9tcGlcbiAqIEBtb2R1bGUgbXBpXG4gKi9cbm1vZHVsZS5leHBvcnRzLm1waSA9IHJlcXVpcmUoJy4vdHlwZS9tcGkuanMnKTtcbi8qKlxuICogQHNlZSBtb2R1bGU6dHlwZS9zMmtcbiAqIEBtb2R1bGUgczJrXG4gKi9cbm1vZHVsZS5leHBvcnRzLnMyayA9IHJlcXVpcmUoJy4vdHlwZS9zMmsuanMnKTtcbi8qKlxuICogQHNlZSBtb2R1bGU6dHlwZS9rZXlpZFxuICogQG1vZHVsZSBrZXlpZFxuICovXG5tb2R1bGUuZXhwb3J0cy5rZXlpZCA9IHJlcXVpcmUoJy4vdHlwZS9rZXlpZC5qcycpO1xuLyoqXG4gKiBAc2VlIG1vZHVsZTplbmNvZGluZy9hcm1vclxuICogQG1vZHVsZSBhcm1vclxuICovXG5tb2R1bGUuZXhwb3J0cy5hcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcbm1vZHVsZS5leHBvcnRzLmVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xuLyoqXG4gKiBAc2VlIG1vZHVsZTpjb25maWcvY29uZmlnXG4gKiBAbW9kdWxlIGNvbmZpZ1xuICovXG5tb2R1bGUuZXhwb3J0cy5jb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZy9jb25maWcuanMnKTtcbm1vZHVsZS5leHBvcnRzLmNyeXB0byA9IHJlcXVpcmUoJy4vY3J5cHRvJyk7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEByZXF1aXJlcyBjb25maWdcbiAqIEByZXF1aXJlcyBlbmNvZGluZy9hcm1vclxuICogQHJlcXVpcmVzIGVudW1zXG4gKiBAcmVxdWlyZXMgcGFja2V0XG4gKiBAbW9kdWxlIGtleVxuICovXG5cbnZhciBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldCcpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKSxcbiAgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyksXG4gIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIENsYXNzIHRoYXQgcmVwcmVzZW50cyBhbiBPcGVuUEdQIGtleS4gTXVzdCBjb250YWluIGEgcHJpbWFyeSBrZXkuXG4gKiBDYW4gY29udGFpbiBhZGRpdGlvbmFsIHN1YmtleXMsIHNpZ25hdHVyZXMsIHVzZXIgaWRzLCB1c2VyIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3BhY2tldGxpc3R9IHBhY2tldGxpc3QgVGhlIHBhY2tldHMgdGhhdCBmb3JtIHRoaXMga2V5XG4gKi9cblxuZnVuY3Rpb24gS2V5KHBhY2tldGxpc3QpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEtleSkpIHtcbiAgICByZXR1cm4gbmV3IEtleShwYWNrZXRsaXN0KTtcbiAgfVxuICAvLyBzYW1lIGRhdGEgYXMgaW4gcGFja2V0bGlzdCBidXQgaW4gc3RydWN0dXJlZCBmb3JtXG4gIHRoaXMucHJpbWFyeUtleSA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IG51bGw7XG4gIHRoaXMuZGlyZWN0U2lnbmF0dXJlcyA9IG51bGw7XG4gIHRoaXMudXNlcnMgPSBudWxsO1xuICB0aGlzLnN1YktleXMgPSBudWxsO1xuICB0aGlzLnBhY2tldGxpc3Qyc3RydWN0dXJlKHBhY2tldGxpc3QpO1xuICBpZiAoIXRoaXMucHJpbWFyeUtleSB8fCAhdGhpcy51c2Vycykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXk6IG5lZWQgYXQgbGVhc3Qga2V5IGFuZCB1c2VyIElEIHBhY2tldCcpO1xuICB9XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBwYWNrZXRsaXN0IHRvIHN0cnVjdHVyZWQga2V5IGRhdGFcbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH0gcGFja2V0bGlzdCBUaGUgcGFja2V0cyB0aGF0IGZvcm0gYSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS5wYWNrZXRsaXN0MnN0cnVjdHVyZSA9IGZ1bmN0aW9uKHBhY2tldGxpc3QpIHtcbiAgdmFyIHVzZXIsIHByaW1hcnlLZXlJZCwgc3ViS2V5O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhY2tldGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBzd2l0Y2ggKHBhY2tldGxpc3RbaV0udGFnKSB7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5wdWJsaWNfa2V5OlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X2tleTpcbiAgICAgICAgdGhpcy5wcmltYXJ5S2V5ID0gcGFja2V0bGlzdFtpXTtcbiAgICAgICAgcHJpbWFyeUtleUlkID0gdGhpcy5wcmltYXJ5S2V5LmdldEtleUlkKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQudXNlcmlkOlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQudXNlcl9hdHRyaWJ1dGU6XG4gICAgICAgIHVzZXIgPSBuZXcgVXNlcihwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgaWYgKCF0aGlzLnVzZXJzKSB0aGlzLnVzZXJzID0gW107XG4gICAgICAgIHRoaXMudXNlcnMucHVzaCh1c2VyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5wdWJsaWNfc3Via2V5OlxuICAgICAgY2FzZSBlbnVtcy5wYWNrZXQuc2VjcmV0X3N1YmtleTpcbiAgICAgICAgdXNlciA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5zdWJLZXlzKSB0aGlzLnN1YktleXMgPSBbXTtcbiAgICAgICAgc3ViS2V5ID0gbmV3IFN1YktleShwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgdGhpcy5zdWJLZXlzLnB1c2goc3ViS2V5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGVudW1zLnBhY2tldC5zaWduYXR1cmU6XG4gICAgICAgIHN3aXRjaCAocGFja2V0bGlzdFtpXS5zaWduYXR1cmVUeXBlKSB7XG4gICAgICAgICAgY2FzZSBlbnVtcy5zaWduYXR1cmUuY2VydF9nZW5lcmljOlxuICAgICAgICAgIGNhc2UgZW51bXMuc2lnbmF0dXJlLmNlcnRfcGVyc29uYTpcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X2Nhc3VhbDpcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X3Bvc2l0aXZlOlxuICAgICAgICAgICAgaWYgKHBhY2tldGxpc3RbaV0uaXNzdWVyS2V5SWQuZXF1YWxzKHByaW1hcnlLZXlJZCkpIHtcbiAgICAgICAgICAgICAgaWYgKCF1c2VyLnNlbGZDZXJ0aWZpY2F0aW9ucykgdXNlci5zZWxmQ2VydGlmaWNhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgdXNlci5zZWxmQ2VydGlmaWNhdGlvbnMucHVzaChwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghdXNlci5vdGhlckNlcnRpZmljYXRpb25zKSB1c2VyLm90aGVyQ2VydGlmaWNhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgdXNlci5vdGhlckNlcnRpZmljYXRpb25zLnB1c2gocGFja2V0bGlzdFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5jZXJ0X3Jldm9jYXRpb246XG4gICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICBpZiAoIXVzZXIucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKSB1c2VyLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICB1c2VyLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucy5wdXNoKHBhY2tldGxpc3RbaV0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCF0aGlzLmRpcmVjdFNpZ25hdHVyZXMpIHRoaXMuZGlyZWN0U2lnbmF0dXJlcyA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmRpcmVjdFNpZ25hdHVyZXMucHVzaChwYWNrZXRsaXN0W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgZW51bXMuc2lnbmF0dXJlLmtleTpcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXJlY3RTaWduYXR1cmVzKSB0aGlzLmRpcmVjdFNpZ25hdHVyZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZGlyZWN0U2lnbmF0dXJlcy5wdXNoKHBhY2tldGxpc3RbaV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBlbnVtcy5zaWduYXR1cmUuc3Via2V5X2JpbmRpbmc6XG4gICAgICAgICAgICBzdWJLZXkuYmluZGluZ1NpZ25hdHVyZSA9IHBhY2tldGxpc3RbaV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5rZXlfcmV2b2NhdGlvbjpcbiAgICAgICAgICAgIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IHBhY2tldGxpc3RbaV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGVudW1zLnNpZ25hdHVyZS5zdWJrZXlfcmV2b2NhdGlvbjpcbiAgICAgICAgICAgIHN1YktleS5yZXZvY2F0aW9uU2lnbmF0dXJlID0gcGFja2V0bGlzdFtpXTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIHN0cnVjdHVyZWQga2V5IGRhdGEgdG8gcGFja2V0bGlzdFxuICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fSBUaGUgcGFja2V0cyB0aGF0IGZvcm0gYSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMucHJpbWFyeUtleSk7XG4gIHBhY2tldGxpc3QucHVzaCh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUpO1xuICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLmRpcmVjdFNpZ25hdHVyZXMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudXNlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLnVzZXJzW2ldLnRvUGFja2V0bGlzdCgpKTtcbiAgfVxuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhY2tldGxpc3QuY29uY2F0KHRoaXMuc3ViS2V5c1tpXS50b1BhY2tldGxpc3QoKSk7XG4gICAgfSBcbiAgfVxuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKiBcbiAqIFJldHVybnMgdGhlIHByaW1hcnkga2V5IHBhY2tldCAoc2VjcmV0IG9yIHB1YmxpYylcbiAqIEByZXR1cm5zIHsobW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleXxudWxsKX0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5UGFja2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnByaW1hcnlLZXk7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGFsbCB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIHN1YmtleSBwYWNrZXRzXG4gKiBAcmV0dXJucyB7QXJyYXk8KG1vZHVsZTpwYWNrZXQvcHVibGljX3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9zdWJrZXkpPn0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0U3Via2V5UGFja2V0cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc3ViS2V5cyA9IFtdO1xuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN1YktleXMucHVzaCh0aGlzLnN1YktleXNbaV0uc3ViS2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1YktleXM7XG59O1xuXG4vKiogXG4gKiBSZXR1cm5zIGFsbCB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIGtleSBhbmQgc3Via2V5IHBhY2tldHNcbiAqIEByZXR1cm5zIHtBcnJheTwobW9kdWxlOnBhY2tldC9wdWJsaWNfc3Via2V5fG1vZHVsZTpwYWNrZXQvc2VjcmV0X3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5KT59IFxuICovXG5LZXkucHJvdG90eXBlLmdldEFsbEtleVBhY2tldHMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIFt0aGlzLmdldEtleVBhY2tldCgpXS5jb25jYXQodGhpcy5nZXRTdWJrZXlQYWNrZXRzKCkpO1xufTtcblxuLyoqIFxuICogUmV0dXJucyBrZXkgSURzIG9mIGFsbCBrZXkgcGFja2V0c1xuICogQHJldHVybnMge0FycmF5PG1vZHVsZTp0eXBlL2tleWlkPn0gXG4gKi9cbktleS5wcm90b3R5cGUuZ2V0S2V5SWRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlJZHMgPSBbXTtcbiAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAga2V5SWRzLnB1c2goa2V5c1tpXS5nZXRLZXlJZCgpKTtcbiAgfVxuICByZXR1cm4ga2V5SWRzO1xufTtcblxuZnVuY3Rpb24gZmluZEtleShrZXlzLCBrZXlJZHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleUlkID0ga2V5c1tpXS5nZXRLZXlJZCgpOyBcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGtleUlkLmVxdWFscyhrZXlJZHNbal0pKSB7XG4gICAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHB1YmxpYyBrZXkgcGFja2V0IGZvciBnaXZlbiBhcnJheSBvZiBrZXkgSURzXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6dHlwZS9rZXlpZD59IGtleUlkcyBcbiAqIEByZXR1cm4geyhtb2R1bGU6cGFja2V0L3B1YmxpY19zdWJrZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fG51bGwpfVxuICovXG5LZXkucHJvdG90eXBlLmdldFB1YmxpY0tleVBhY2tldCA9IGZ1bmN0aW9uKGtleUlkcykge1xuICBpZiAodGhpcy5wcmltYXJ5S2V5LnRhZyA9PSBlbnVtcy5wYWNrZXQucHVibGljX2tleSkge1xuICAgIHJldHVybiBmaW5kS2V5KHRoaXMuZ2V0QWxsS2V5UGFja2V0cygpLCBrZXlJZHMpOyAgXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gIFxufTtcblxuLyoqXG4gKiBSZXR1cm5zIGZpcnN0IHByaXZhdGUga2V5IHBhY2tldCBmb3IgZ2l2ZW4gYXJyYXkgb2Yga2V5IElEc1xuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOnR5cGUva2V5aWQ+fSBrZXlJZHNcbiAqIEByZXR1cm4geyhtb2R1bGU6cGFja2V0L3NlY3JldF9zdWJrZXl8bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG51bGwpfVxuICovXG5LZXkucHJvdG90eXBlLmdldFByaXZhdGVLZXlQYWNrZXQgPSBmdW5jdGlvbihrZXlJZHMpIHtcbiAgaWYgKHRoaXMucHJpbWFyeUtleS50YWcgPT0gZW51bXMucGFja2V0LnNlY3JldF9rZXkpIHtcbiAgICByZXR1cm4gZmluZEtleSh0aGlzLmdldEFsbEtleVBhY2tldHMoKSwga2V5SWRzKTsgIFxuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgdXNlcmlkc1xuICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gYXJyYXkgb2YgdXNlcmlkc1xuICovXG5LZXkucHJvdG90eXBlLmdldFVzZXJJZHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHVzZXJpZHMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRoaXMudXNlcnNbaV0udXNlcklkKSB7XG4gICAgICB1c2VyaWRzLnB1c2godGhpcy51c2Vyc1tpXS51c2VySWQud3JpdGUoKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB1c2VyaWRzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHB1YmxpYyBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQdWJsaWMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucHJpbWFyeUtleS50YWcgPT0gZW51bXMucGFja2V0LnB1YmxpY19rZXk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbktleS5wcm90b3R5cGUuaXNQcml2YXRlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnByaW1hcnlLZXkudGFnID09IGVudW1zLnBhY2tldC5zZWNyZXRfa2V5O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGtleSBhcyBwdWJsaWMga2V5IChzaGFsbG93IGNvcHkpXG4gKiBAcmV0dXJuIHttb2R1bGU6a2V5fktleX0gbmV3IHB1YmxpYyBLZXlcbiAqL1xuS2V5LnByb3RvdHlwZS50b1B1YmxpYyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICB2YXIga2V5UGFja2V0cyA9IHRoaXMudG9QYWNrZXRsaXN0KCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5UGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgIHN3aXRjaCAoa2V5UGFja2V0c1tpXS50YWcpIHtcbiAgICAgIGNhc2UgZW51bXMucGFja2V0LnNlY3JldF9rZXk6XG4gICAgICAgIHZhciBieXRlcyA9IGtleVBhY2tldHNbaV0ud3JpdGVQdWJsaWNLZXkoKTtcbiAgICAgICAgdmFyIHB1YktleVBhY2tldCA9IG5ldyBwYWNrZXQucHVibGljX2tleSgpO1xuICAgICAgICBwdWJLZXlQYWNrZXQucmVhZChieXRlcyk7XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChwdWJLZXlQYWNrZXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgZW51bXMucGFja2V0LnNlY3JldF9zdWJrZXk6XG4gICAgICAgIHZhciBieXRlcyA9IGtleVBhY2tldHNbaV0ud3JpdGVQdWJsaWNLZXkoKTtcbiAgICAgICAgdmFyIHB1YlN1YmtleVBhY2tldCA9IG5ldyBwYWNrZXQucHVibGljX3N1YmtleSgpO1xuICAgICAgICBwdWJTdWJrZXlQYWNrZXQucmVhZChieXRlcyk7XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChwdWJTdWJrZXlQYWNrZXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBhY2tldGxpc3QucHVzaChrZXlQYWNrZXRzW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIGtleVxuICogQHJldHVybiB7U3RyaW5nfSBBU0NJSSBhcm1vclxuICovXG5LZXkucHJvdG90eXBlLmFybW9yID0gZnVuY3Rpb24oKSB7XG4gIHZhciB0eXBlID0gdGhpcy5pc1B1YmxpYygpID8gZW51bXMuYXJtb3IucHVibGljX2tleSA6IGVudW1zLmFybW9yLnByaXZhdGVfa2V5O1xuICByZXR1cm4gYXJtb3IuZW5jb2RlKHR5cGUsIHRoaXMudG9QYWNrZXRsaXN0KCkud3JpdGUoKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgZmlyc3Qga2V5IHBhY2tldCB0aGF0IGlzIGF2YWlsYWJsZSBmb3Igc2lnbmluZ1xuICogQHJldHVybiB7KG1vZHVsZTpwYWNrZXQvc2VjcmV0X3N1YmtleXxtb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bnVsbCl9IGtleSBwYWNrZXQgb3IgbnVsbCBpZiBubyBzaWduaW5nIGtleSBoYXMgYmVlbiBmb3VuZFxuICovXG5LZXkucHJvdG90eXBlLmdldFNpZ25pbmdLZXlQYWNrZXQgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNQdWJsaWMoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTmVlZCBwcml2YXRlIGtleSBmb3Igc2lnbmluZycpO1xuICB9XG4gIHZhciBwcmltYXJ5VXNlciA9IHRoaXMuZ2V0UHJpbWFyeVVzZXIoKTtcbiAgaWYgKHByaW1hcnlVc2VyICYmIFxuICAgICAgaXNWYWxpZFNpZ25pbmdLZXlQYWNrZXQodGhpcy5wcmltYXJ5S2V5LCBwcmltYXJ5VXNlci5zZWxmQ2VydGlmaWNhdGUpKSB7XG4gICAgcmV0dXJuIHRoaXMucHJpbWFyeUtleTtcbiAgfVxuICBpZiAodGhpcy5zdWJLZXlzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YktleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLnN1YktleXNbaV0uaXNWYWxpZFNpZ25pbmdLZXkodGhpcy5wcmltYXJ5S2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdWJLZXlzW2ldLnN1YktleTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgcHJlZmVycmVkIHNpZ25hdHVyZSBoYXNoIGFsZ29yaXRobSBvZiB0aGlzIGtleVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5LZXkucHJvdG90eXBlLmdldFByZWZlcnJlZEhhc2hBbGdvcml0aG0gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHByaW1hcnlVc2VyID0gdGhpcy5nZXRQcmltYXJ5VXNlcigpO1xuICBpZiAocHJpbWFyeVVzZXIgJiYgcHJpbWFyeVVzZXIuc2VsZkNlcnRpZmljYXRlLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zKSB7XG4gICAgcmV0dXJuIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtc1swXTtcbiAgfVxuICByZXR1cm4gY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobTtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRFbmNyeXB0aW9uS2V5UGFja2V0KGtleVBhY2tldCwgc2lnbmF0dXJlKSB7XG4gIHJldHVybiBrZXlQYWNrZXQuYWxnb3JpdGhtICE9PSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgZW51bXMucHVibGljS2V5LmRzYSkgJiZcbiAgICAgICAgIGtleVBhY2tldC5hbGdvcml0aG0gIT09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkucnNhX3NpZ24pICYmXG4gICAgICAgICAoKHNpZ25hdHVyZS5rZXlGbGFncyAmIGVudW1zLmtleUZsYWdzLmVuY3J5cHRfY29tbXVuaWNhdGlvbikgIT09IDAgfHxcbiAgICAgICAgICAoc2lnbmF0dXJlLmtleUZsYWdzICYgZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9zdG9yYWdlKSAhPT0gMCB8fFxuICAgICAgICAgICFzaWduYXR1cmUua2V5RmxhZ3MpO1xufTtcblxuZnVuY3Rpb24gaXNWYWxpZFNpZ25pbmdLZXlQYWNrZXQoa2V5UGFja2V0LCBzaWduYXR1cmUpIHtcbiAgcmV0dXJuIChrZXlQYWNrZXQuYWxnb3JpdGhtID09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkuZHNhKSB8fFxuICAgICAgICAgIGtleVBhY2tldC5hbGdvcml0aG0gPT0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGVudW1zLnB1YmxpY0tleS5yc2Ffc2lnbikgfHxcbiAgICAgICAgICBrZXlQYWNrZXQuYWxnb3JpdGhtID09IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBlbnVtcy5wdWJsaWNLZXkucnNhX2VuY3J5cHRfc2lnbikpICYmXG4gICAgICAgICAoKHNpZ25hdHVyZS5rZXlGbGFncyAmIGVudW1zLmtleUZsYWdzLnNpZ25fZGF0YSkgIT09IDAgfHxcbiAgICAgICAgICAhc2lnbmF0dXJlLmtleUZsYWdzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgdmFsaWQgZW5jcnlwdGlvbiBrZXkgcGFja2V0IGZvciB0aGlzIGtleVxuICogQHJldHVybnMgeyhtb2R1bGU6cGFja2V0L3B1YmxpY19zdWJrZXl8bW9kdWxlOnBhY2tldC9zZWNyZXRfc3Via2V5fG1vZHVsZTpwYWNrZXQvc2VjcmV0X2tleXxtb2R1bGU6cGFja2V0L3B1YmxpY19rZXl8bnVsbCl9IGtleSBwYWNrZXQgb3IgbnVsbCBpZiBubyBlbmNyeXB0aW9uIGtleSBoYXMgYmVlbiBmb3VuZFxuICovXG5LZXkucHJvdG90eXBlLmdldEVuY3J5cHRpb25LZXlQYWNrZXQgPSBmdW5jdGlvbigpIHtcbiAgLy8gVjQ6IGJ5IGNvbnZlbnRpb24gc3Via2V5cyBhcmUgcHJlZmVyZWQgZm9yIGVuY3J5cHRpb24gc2VydmljZVxuICAvLyBWMzoga2V5cyBNVVNUIE5PVCBoYXZlIHN1YmtleXNcbiAgaWYgKHRoaXMuc3ViS2V5cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5zdWJLZXlzW2ldLmlzVmFsaWRFbmNyeXB0aW9uS2V5KHRoaXMucHJpbWFyeUtleSkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViS2V5c1tpXS5zdWJLZXk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIGlmIG5vIHZhbGlkIHN1YmtleSBmb3IgZW5jcnlwdGlvbiwgZXZhbHVhdGUgcHJpbWFyeSBrZXlcbiAgdmFyIHByaW1hcnlVc2VyID0gdGhpcy5nZXRQcmltYXJ5VXNlcigpO1xuICBpZiAocHJpbWFyeVVzZXIgJiYgXG4gICAgICBpc1ZhbGlkRW5jcnlwdGlvbktleVBhY2tldCh0aGlzLnByaW1hcnlLZXksIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZSkpIHtcbiAgICByZXR1cm4gdGhpcy5wcmltYXJ5S2V5O1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBEZWNyeXB0cyBhbGwgc2VjcmV0IGtleSBhbmQgc3Via2V5IHBhY2tldHNcbiAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3BocmFzZSBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIGtleSBhbmQgc3Via2V5IHBhY2tldHMgZGVjcnlwdGVkIHN1Y2Nlc3NmdWxseVxuICovXG5LZXkucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG4gIGlmICh0aGlzLmlzUHJpdmF0ZSgpKSB7XG4gICAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzdWNjZXNzID0ga2V5c1tpXS5kZWNyeXB0KHBhc3NwaHJhc2UpO1xuICAgICAgaWYgKCFzdWNjZXNzKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdGhpbmcgdG8gZGVjcnlwdCBpbiBhIHB1YmxpYyBrZXlcIik7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIERlY3J5cHRzIHNwZWNpZmljIGtleSBwYWNrZXRzIGJ5IGtleSBJRFxuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOnR5cGUva2V5aWQ+fSBrZXlJZHNcbiAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3BocmFzZSBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIGtleSBwYWNrZXRzIGRlY3J5cHRlZCBzdWNjZXNzZnVsbHlcbiAqL1xuS2V5LnByb3RvdHlwZS5kZWNyeXB0S2V5UGFja2V0ID0gZnVuY3Rpb24oa2V5SWRzLCBwYXNzcGhyYXNlKSB7XG4gIGlmICh0aGlzLmlzUHJpdmF0ZSgpKSB7XG4gICAgdmFyIGtleXMgPSB0aGlzLmdldEFsbEtleVBhY2tldHMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXlJZCA9IGtleXNbaV0uZ2V0S2V5SWQoKTsgXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleUlkcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoa2V5SWQuZXF1YWxzKGtleUlkc1tqXSkpIHtcbiAgICAgICAgICB2YXIgc3VjY2VzcyA9IGtleXNbaV0uZGVjcnlwdChwYXNzcGhyYXNlKTtcbiAgICAgICAgICBpZiAoIXN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3RoaW5nIHRvIGRlY3J5cHQgaW4gYSBwdWJsaWMga2V5XCIpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgcHJpbWFyeSBrZXkuIENoZWNrcyBmb3IgcmV2b2NhdGlvbiBzaWduYXR1cmVzLCBleHBpcmF0aW9uIHRpbWVcbiAqIGFuZCB2YWxpZCBzZWxmIHNpZ25hdHVyZVxuICogQHJldHVybiB7bW9kdWxlOmVudW1zLmtleVN0YXR1c30gVGhlIHN0YXR1cyBvZiB0aGUgcHJpbWFyeSBrZXlcbiAqL1xuS2V5LnByb3RvdHlwZS52ZXJpZnlQcmltYXJ5S2V5ID0gZnVuY3Rpb24oKSB7XG4gIC8vIGNoZWNrIHJldm9jYXRpb24gc2lnbmF0dXJlXG4gIGlmICh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUgJiYgIXRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS5pc0V4cGlyZWQoKSAmJiBcbiAgICAgKHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS52ZXJpZmllZCB8fCBcbiAgICAgIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZS52ZXJpZnkodGhpcy5wcmltYXJ5S2V5LCB7a2V5OiB0aGlzLnByaW1hcnlLZXl9KSkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLnJldm9rZWQ7XG4gIH1cbiAgLy8gY2hlY2sgVjMgZXhwaXJhdGlvbiB0aW1lXG4gIGlmICh0aGlzLnByaW1hcnlLZXkudmVyc2lvbiA9PSAzICYmIHRoaXMucHJpbWFyeUtleS5leHBpcmF0aW9uVGltZVYzICE9PSAwICYmXG4gICAgRGF0ZS5ub3coKSA+ICh0aGlzLnByaW1hcnlLZXkuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnByaW1hcnlLZXkuZXhwaXJhdGlvblRpbWVWMyoyNCozNjAwKjEwMDApKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5leHBpcmVkO1xuICB9XG4gIC8vIGNoZWNrIGZvciBhdCBsZWFzdCBvbmUgc2VsZiBzaWduYXR1cmUuIFNlbGYgc2lnbmF0dXJlIG9mIHVzZXIgSUQgbm90IG1hbmRhdG9yeVxuICAvLyBTZWUgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg4MCNzZWN0aW9uLTExLjFcbiAgdmFyIHNlbGZTaWduZWQgPSBmYWxzZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRoaXMudXNlcnNbaV0udXNlcklkICYmIHRoaXMudXNlcnNbaV0uc2VsZkNlcnRpZmljYXRpb25zKSB7XG4gICAgICBzZWxmU2lnbmVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKCFzZWxmU2lnbmVkKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5ub19zZWxmX2NlcnQ7XG4gIH1cbiAgLy8gY2hlY2sgZm9yIHZhbGlkIHNlbGYgc2lnbmF0dXJlXG4gIHZhciBwcmltYXJ5VXNlciA9IHRoaXMuZ2V0UHJpbWFyeVVzZXIoKTtcbiAgaWYgKCFwcmltYXJ5VXNlcikge1xuICAgIHJldHVybiBlbnVtcy5rZXlTdGF0dXMuaW52YWxpZDtcbiAgfVxuICAvLyBjaGVjayBWNCBleHBpcmF0aW9uIHRpbWVcbiAgaWYgKHRoaXMucHJpbWFyeUtleS52ZXJzaW9uID09IDQgJiYgcHJpbWFyeVVzZXIuc2VsZkNlcnRpZmljYXRlLmtleU5ldmVyRXhwaXJlcyA9PT0gZmFsc2UgJiZcbiAgICBEYXRlLm5vdygpID4gKHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5jcmVhdGVkLmdldFRpbWUoKSArIHByaW1hcnlVc2VyLnNlbGZDZXJ0aWZpY2F0ZS5rZXlFeHBpcmF0aW9uVGltZSoxMDAwKSkge1xuICAgIHJldHVybiBlbnVtcy5rZXlTdGF0dXMuZXhwaXJlZDtcbiAgfVxuICByZXR1cm4gZW51bXMua2V5U3RhdHVzLnZhbGlkO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHByaW1hcnkgdXNlciBhbmQgbW9zdCBzaWduaWZpY2FudCAobGF0ZXN0IHZhbGlkKSBzZWxmIHNpZ25hdHVyZVxuICogLSBpZiBtdWx0aXBsZSB1c2VycyBhcmUgbWFya2VkIGFzIHByaW1hcnkgdXNlcnMgcmV0dXJucyB0aGUgb25lIHdpdGggdGhlIGxhdGVzdCBzZWxmIHNpZ25hdHVyZVxuICogLSBpZiBubyBwcmltYXJ5IHVzZXIgaXMgZm91bmQgcmV0dXJucyB0aGUgdXNlciB3aXRoIHRoZSBsYXRlc3Qgc2VsZiBzaWduYXR1cmVcbiAqIEByZXR1cm4ge3t1c2VyOiBBcnJheTxtb2R1bGU6cGFja2V0L1VzZXI+LCBzZWxmQ2VydGlmaWNhdGU6IEFycmF5PG1vZHVsZTpwYWNrZXQvc2lnbmF0dXJlPn19IFRoZSBwcmltYXJ5IHVzZXIgYW5kIHRoZSBzZWxmIHNpZ25hdHVyZVxuICovXG5LZXkucHJvdG90eXBlLmdldFByaW1hcnlVc2VyID0gZnVuY3Rpb24oKSB7XG4gIHZhciB1c2VyID0gbnVsbDtcbiAgdmFyIHVzZXJTZWxmQ2VydDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCF0aGlzLnVzZXJzW2ldLnVzZXJJZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBzZWxmQ2VydCA9IHRoaXMudXNlcnNbaV0uZ2V0VmFsaWRTZWxmQ2VydGlmaWNhdGUodGhpcy5wcmltYXJ5S2V5KTtcbiAgICBpZiAoIXNlbGZDZXJ0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCF1c2VyIHx8IFxuICAgICAgICAhdXNlclNlbGZDZXJ0LmlzUHJpbWFyeVVzZXJJRCAmJiBzZWxmQ2VydC5pc1ByaW1hcnlVc2VySUQgfHxcbiAgICAgICAgIHVzZXJTZWxmQ2VydC5jcmVhdGVkIDwgc2VsZkNlcnQuY3JlYXRlZCkge1xuICAgICAgdXNlciA9IHRoaXMudXNlcnNbaV07XG4gICAgICB1c2VyU2VsZkNlcnQgPSBzZWxmQ2VydDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVzZXIgPyB7dXNlcjogdXNlciwgc2VsZkNlcnRpZmljYXRlOiB1c2VyU2VsZkNlcnR9IDogbnVsbDtcbn1cblxuLy8gVE9ET1xuS2V5LnByb3RvdHlwZS5yZXZva2UgPSBmdW5jdGlvbigpIHtcblxufTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIHVzZXIgSUQgb3IgYXR0cmlidXRlIHBhY2tldCBhbmQgdGhlIHJlbGV2YW50IHNpZ25hdHVyZXMuXG4gKi9cbmZ1bmN0aW9uIFVzZXIodXNlclBhY2tldCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVXNlcikpIHtcbiAgICByZXR1cm4gbmV3IFVzZXIodXNlclBhY2tldCk7XG4gIH1cbiAgdGhpcy51c2VySWQgPSB1c2VyUGFja2V0LnRhZyA9PSBlbnVtcy5wYWNrZXQudXNlcmlkID8gdXNlclBhY2tldCA6IG51bGw7XG4gIHRoaXMudXNlckF0dHJpYnV0ZSA9IHVzZXJQYWNrZXQudGFnID09IGVudW1zLnBhY2tldC51c2VyX2F0dHJpYnV0ZSA/IHVzZXJQYWNrZXQgOiBudWxsXG4gIHRoaXMuc2VsZkNlcnRpZmljYXRpb25zID0gbnVsbDtcbiAgdGhpcy5vdGhlckNlcnRpZmljYXRpb25zID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uQ2VydGlmaWNhdGlvbnMgPSBudWxsO1xufVxuXG4vKipcbiAqIFRyYW5zZm9ybXMgc3RydWN0dXJlZCB1c2VyIGRhdGEgdG8gcGFja2V0bGlzdFxuICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fVxuICovXG5Vc2VyLnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMudXNlcklkIHx8IHRoaXMudXNlckF0dHJpYnV0ZSk7XG4gIHBhY2tldGxpc3QuY29uY2F0KHRoaXMucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKTtcbiAgcGFja2V0bGlzdC5jb25jYXQodGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMpO1xuICBwYWNrZXRsaXN0LmNvbmNhdCh0aGlzLm90aGVyQ2VydGlmaWNhdGlvbnMpO1xuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgc2VsZiBzaWduYXR1cmUgb2YgdGhlIHVzZXIgaXMgcmV2b2tlZFxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zaWduYXR1cmV9ICAgICAgICAgICAgICAgICAgICBjZXJ0aWZpY2F0ZVxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0gcHJpbWFyeUtleSAgVGhlIHByaW1hcnkga2V5IHBhY2tldFxuICogQHJldHVybiB7Qm9vbGVhbn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRydWUgaWYgdGhlIGNlcnRpZmljYXRlIGlzIHJldm9rZWRcbiAqL1xuVXNlci5wcm90b3R5cGUuaXNSZXZva2VkID0gZnVuY3Rpb24oY2VydGlmaWNhdGUsIHByaW1hcnlLZXkpIHtcbiAgaWYgKHRoaXMucmV2b2NhdGlvbkNlcnRpZmljYXRpb25zKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHJldHVybiB0aGlzLnJldm9jYXRpb25DZXJ0aWZpY2F0aW9ucy5zb21lKGZ1bmN0aW9uKHJldkNlcnQpIHtcbiAgICAgICAgICAgICByZXR1cm4gcmV2Q2VydC5pc3N1ZXJLZXlJZC5lcXVhbHMoY2VydGlmaWNhdGUuaXNzdWVyS2V5SWQpICYmXG4gICAgICAgICAgICAgICAgICAgICFyZXZDZXJ0LmlzRXhwaXJlZCgpICYmIFxuICAgICAgICAgICAgICAgICAgICAocmV2Q2VydC52ZXJpZmllZCB8fCBcbiAgICAgICAgICAgICAgICAgICAgIHJldkNlcnQudmVyaWZ5KHByaW1hcnlLZXksIHt1c2VyaWQ6IHRoYXQudXNlcklkIHx8IHRoYXQudXNlckF0dHJpYnV0ZSwga2V5OiBwcmltYXJ5S2V5fSkpO1xuICAgICAgICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtb3N0IHNpZ25pZmljYW50IChsYXRlc3QgdmFsaWQpIHNlbGYgc2lnbmF0dXJlIG9mIHRoZSB1c2VyXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fSBwcmltYXJ5S2V5IFRoZSBwcmltYXJ5IGtleSBwYWNrZXRcbiAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvc2lnbmF0dXJlfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgc2VsZiBzaWduYXR1cmVcbiAqL1xuVXNlci5wcm90b3R5cGUuZ2V0VmFsaWRTZWxmQ2VydGlmaWNhdGUgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIGlmICghdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgdmFsaWRDZXJ0ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGhpcy5pc1Jldm9rZWQodGhpcy5zZWxmQ2VydGlmaWNhdGlvbnNbaV0sIHByaW1hcnlLZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS5pc0V4cGlyZWQoKSAmJlxuICAgICAgICh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS52ZXJpZmllZCB8fCBcbiAgICAgICAgdGhpcy5zZWxmQ2VydGlmaWNhdGlvbnNbaV0udmVyaWZ5KHByaW1hcnlLZXksIHt1c2VyaWQ6IHRoaXMudXNlcklkIHx8IHRoaXMudXNlckF0dHJpYnV0ZSwga2V5OiBwcmltYXJ5S2V5fSkpKSB7XG4gICAgICB2YWxpZENlcnQucHVzaCh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXSk7XG4gICAgfVxuICB9XG4gIC8vIG1vc3QgcmVjZW50IGZpcnN0XG4gIHZhbGlkQ2VydCA9IHZhbGlkQ2VydC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICBhID0gYS5jcmVhdGVkO1xuICAgIGIgPSBiLmNyZWF0ZWQ7XG4gICAgcmV0dXJuIGE+YiA/IC0xIDogYTxiID8gMSA6IDA7XG4gIH0pO1xuICByZXR1cm4gdmFsaWRDZXJ0WzBdO1xufTtcblxuLyoqXG4gKiBWZXJpZnkgVXNlci4gQ2hlY2tzIGZvciBleGlzdGVuY2Ugb2Ygc2VsZiBzaWduYXR1cmVzLCByZXZvY2F0aW9uIHNpZ25hdHVyZXNcbiAqIGFuZCB2YWxpZGl0eSBvZiBzZWxmIHNpZ25hdHVyZVxuICogQHBhcmFtICB7bW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0gcHJpbWFyeUtleSBUaGUgcHJpbWFyeSBrZXkgcGFja2V0XG4gKiBAcmV0dXJuIHttb2R1bGU6ZW51bXMua2V5U3RhdHVzfSBzdGF0dXMgb2YgdXNlciAgICBcbiAqL1xuVXNlci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24ocHJpbWFyeUtleSkge1xuICBpZiAoIXRoaXMuc2VsZkNlcnRpZmljYXRpb25zKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5ub19zZWxmX2NlcnQ7XG4gIH1cbiAgdmFyIHN0YXR1cztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNlbGZDZXJ0aWZpY2F0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0aGlzLmlzUmV2b2tlZCh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXSwgcHJpbWFyeUtleSkpIHtcbiAgICAgIHN0YXR1cyA9IGVudW1zLmtleVN0YXR1cy5yZXZva2VkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICghKHRoaXMuc2VsZkNlcnRpZmljYXRpb25zW2ldLnZlcmlmaWVkIHx8IFxuICAgICAgICB0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS52ZXJpZnkocHJpbWFyeUtleSwge3VzZXJpZDogdGhpcy51c2VySWQgfHwgdGhpcy51c2VyQXR0cmlidXRlLCBrZXk6IHByaW1hcnlLZXl9KSkpIHtcbiAgICAgIHN0YXR1cyA9IGVudW1zLmtleVN0YXR1cy5pbnZhbGlkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlbGZDZXJ0aWZpY2F0aW9uc1tpXS5pc0V4cGlyZWQoKSkge1xuICAgICAgc3RhdHVzID0gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgc3RhdHVzID0gZW51bXMua2V5U3RhdHVzLnZhbGlkO1xuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiBzdGF0dXM7XG59O1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBDbGFzcyB0aGF0IHJlcHJlc2VudHMgYSBzdWJrZXkgcGFja2V0IGFuZCB0aGUgcmVsZXZhbnQgc2lnbmF0dXJlcy5cbiAqL1xuZnVuY3Rpb24gU3ViS2V5KHN1YktleVBhY2tldCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU3ViS2V5KSkge1xuICAgIHJldHVybiBuZXcgU3ViS2V5KHN1YktleVBhY2tldCk7XG4gIH1cbiAgdGhpcy5zdWJLZXkgPSBzdWJLZXlQYWNrZXQ7XG4gIHRoaXMuYmluZGluZ1NpZ25hdHVyZSA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSA9IG51bGw7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBzdHJ1Y3R1cmVkIHN1YmtleSBkYXRhIHRvIHBhY2tldGxpc3RcbiAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH1cbiAqL1xuU3ViS2V5LnByb3RvdHlwZS50b1BhY2tldGxpc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMuc3ViS2V5KTtcbiAgcGFja2V0bGlzdC5wdXNoKHRoaXMucmV2b2NhdGlvblNpZ25hdHVyZSk7XG4gIHBhY2tldGxpc3QucHVzaCh0aGlzLmJpbmRpbmdTaWduYXR1cmUpO1xuICByZXR1cm4gcGFja2V0bGlzdDtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzdWJrZXkgY2FuIGJlIHVzZWQgZm9yIGVuY3J5cHRpb25cbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvc2VjcmV0X2tleXxtb2R1bGU6cGFja2V0L3B1YmxpY19rZXl9ICBwcmltYXJ5S2V5IFRoZSBwcmltYXJ5IGtleSBwYWNrZXRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblN1YktleS5wcm90b3R5cGUuaXNWYWxpZEVuY3J5cHRpb25LZXkgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIHJldHVybiB0aGlzLnZlcmlmeShwcmltYXJ5S2V5KSA9PSBlbnVtcy5rZXlTdGF0dXMudmFsaWQgJiZcbiAgICAgICAgIGlzVmFsaWRFbmNyeXB0aW9uS2V5UGFja2V0KHRoaXMuc3ViS2V5LCB0aGlzLmJpbmRpbmdTaWduYXR1cmUpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHN1YmtleSBjYW4gYmUgdXNlZCBmb3Igc2lnbmluZyBvZiBkYXRhXG4gKiBAcGFyYW0gIHttb2R1bGU6cGFja2V0L3NlY3JldF9rZXl8bW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5fSAgcHJpbWFyeUtleSBUaGUgcHJpbWFyeSBrZXkgcGFja2V0XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5TdWJLZXkucHJvdG90eXBlLmlzVmFsaWRTaWduaW5nS2V5ID0gZnVuY3Rpb24ocHJpbWFyeUtleSkge1xuICByZXR1cm4gdGhpcy52ZXJpZnkocHJpbWFyeUtleSkgPT0gZW51bXMua2V5U3RhdHVzLnZhbGlkICYmXG4gICAgICAgICBpc1ZhbGlkU2lnbmluZ0tleVBhY2tldCh0aGlzLnN1YktleSwgdGhpcy5iaW5kaW5nU2lnbmF0dXJlKTtcbn07XG5cbi8qKlxuICogVmVyaWZ5IHN1YmtleS4gQ2hlY2tzIGZvciByZXZvY2F0aW9uIHNpZ25hdHVyZXMsIGV4cGlyYXRpb24gdGltZVxuICogYW5kIHZhbGlkIGJpbmRpbmcgc2lnbmF0dXJlXG4gKiBAcmV0dXJuIHttb2R1bGU6ZW51bXMua2V5U3RhdHVzfSBUaGUgc3RhdHVzIG9mIHRoZSBzdWJrZXlcbiAqL1xuU3ViS2V5LnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbihwcmltYXJ5S2V5KSB7XG4gIC8vIGNoZWNrIHN1YmtleSByZXZvY2F0aW9uIHNpZ25hdHVyZVxuICBpZiAodGhpcy5yZXZvY2F0aW9uU2lnbmF0dXJlICYmICF0aGlzLnJldm9jYXRpb25TaWduYXR1cmUuaXNFeHBpcmVkKCkgJiYgXG4gICAgICh0aGlzLnJldm9jYXRpb25TaWduYXR1cmUudmVyaWZpZWQgfHwgXG4gICAgICB0aGlzLnJldm9jYXRpb25TaWduYXR1cmUudmVyaWZ5KHByaW1hcnlLZXksIHtrZXk6IHRoaXMuc3ViS2V5fSkpKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5yZXZva2VkO1xuICB9XG4gIC8vIGNoZWNrIFYzIGV4cGlyYXRpb24gdGltZVxuICBpZiAodGhpcy5zdWJLZXkudmVyc2lvbiA9PSAzICYmIHRoaXMuc3ViS2V5LmV4cGlyYXRpb25UaW1lVjMgIT09IDAgJiZcbiAgICAgIERhdGUubm93KCkgPiAodGhpcy5zdWJLZXkuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnN1YktleS5leHBpcmF0aW9uVGltZVYzKjI0KjM2MDAqMTAwMCkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gIH1cbiAgLy8gY2hlY2sgc3Via2V5IGJpbmRpbmcgc2lnbmF0dXJlXG4gIGlmICghdGhpcy5iaW5kaW5nU2lnbmF0dXJlKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5pbnZhbGlkO1xuICB9XG4gIGlmICh0aGlzLmJpbmRpbmdTaWduYXR1cmUuaXNFeHBpcmVkKCkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmV4cGlyZWQ7XG4gIH1cbiAgaWYgKCEodGhpcy5iaW5kaW5nU2lnbmF0dXJlLnZlcmlmaWVkIHx8XG4gICAgICAgIHRoaXMuYmluZGluZ1NpZ25hdHVyZS52ZXJpZnkocHJpbWFyeUtleSwge2tleTogcHJpbWFyeUtleSwgYmluZDogdGhpcy5zdWJLZXl9KSkpIHtcbiAgICByZXR1cm4gZW51bXMua2V5U3RhdHVzLmludmFsaWQ7XG4gIH1cbiAgLy8gY2hlY2sgVjQgZXhwaXJhdGlvbiB0aW1lXG4gIGlmICh0aGlzLnN1YktleS52ZXJzaW9uID09IDQgJiZcbiAgICAgIHRoaXMuYmluZGluZ1NpZ25hdHVyZS5rZXlOZXZlckV4cGlyZXMgPT09IGZhbHNlICYmXG4gICAgICBEYXRlLm5vdygpID4gKHRoaXMuc3ViS2V5LmNyZWF0ZWQuZ2V0VGltZSgpICsgdGhpcy5iaW5kaW5nU2lnbmF0dXJlLmtleUV4cGlyYXRpb25UaW1lKjEwMDApKSB7XG4gICAgcmV0dXJuIGVudW1zLmtleVN0YXR1cy5leHBpcmVkO1xuICB9XG4gIHJldHVybiBlbnVtcy5rZXlTdGF0dXMudmFsaWQ7XG59O1xuXG4vKipcbiAqIFJlYWRzIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZCByZXR1cm5zIG9uZSBvciBtdWx0aXBsZSBrZXkgb2JqZWN0c1xuICogQHBhcmFtIHtTdHJpbmd9IGFybW9yZWRUZXh0IHRleHQgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJuIHt7a2V5czogQXJyYXk8bW9kdWxlOmtleX5LZXk+LCBlcnI6IChBcnJheTxFcnJvcj58bnVsbCl9fSByZXN1bHQgb2JqZWN0IHdpdGgga2V5IGFuZCBlcnJvciBhcnJheXNcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gcmVhZEFybW9yZWQoYXJtb3JlZFRleHQpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICByZXN1bHQua2V5cyA9IFtdO1xuICB0cnkge1xuICAgIHZhciBpbnB1dCA9IGFybW9yLmRlY29kZShhcm1vcmVkVGV4dCk7XG4gICAgaWYgKCEoaW5wdXQudHlwZSA9PSBlbnVtcy5hcm1vci5wdWJsaWNfa2V5IHx8IGlucHV0LnR5cGUgPT0gZW51bXMuYXJtb3IucHJpdmF0ZV9rZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FybW9yZWQgdGV4dCBub3Qgb2YgdHlwZSBrZXknKTtcbiAgICB9XG4gICAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQuZGF0YSk7XG4gICAgdmFyIGtleUluZGV4ID0gcGFja2V0bGlzdC5pbmRleE9mVGFnKGVudW1zLnBhY2tldC5wdWJsaWNfa2V5LCBlbnVtcy5wYWNrZXQuc2VjcmV0X2tleSk7XG4gICAgaWYgKGtleUluZGV4Lmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGtleSBwYWNrZXQgZm91bmQgaW4gYXJtb3JlZCB0ZXh0JylcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlJbmRleC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG9uZUtleUxpc3QgPSBwYWNrZXRsaXN0LnNsaWNlKGtleUluZGV4W2ldLCBrZXlJbmRleFtpICsgMV0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIG5ld0tleSA9IG5ldyBLZXkob25lS2V5TGlzdCk7XG4gICAgICAgIHJlc3VsdC5rZXlzLnB1c2gobmV3S2V5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVzdWx0LmVyciA9IHJlc3VsdC5lcnIgfHwgW107XG4gICAgICAgIHJlc3VsdC5lcnIucHVzaChlKTsgXG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgcmVzdWx0LmVyciA9IHJlc3VsdC5lcnIgfHwgW107XG4gICAgcmVzdWx0LmVyci5wdXNoKGUpOyBcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIG5ldyBPcGVuUEdQIGtleS4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydHMgUlNBIGtleXMuXG4gKiBQcmltYXJ5IGFuZCBzdWJrZXkgd2lsbCBiZSBvZiBzYW1lIHR5cGUuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgICAgdG8gaW5kaWNhdGUgd2hhdCB0eXBlIG9mIGtleSB0byBtYWtlLiBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSU0EgaXMgMS4gU2VlIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzQ4ODAjc2VjdGlvbi05LjFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbnVtQml0cyAgICBudW1iZXIgb2YgYml0cyBmb3IgdGhlIGtleSBjcmVhdGlvbi5cbiAqIEBwYXJhbSB7U3RyaW5nfSAgdXNlcklkICAgICBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiBcIlVzZXIgTmFtZSA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gKiBAcGFyYW0ge1N0cmluZ30gIHBhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBlbmNyeXB0IHRoZSByZXN1bHRpbmcgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge21vZHVsZTprZXl+S2V5fVxuICogQHN0YXRpY1xuICovXG5mdW5jdGlvbiBnZW5lcmF0ZShrZXlUeXBlLCBudW1CaXRzLCB1c2VySWQsIHBhc3NwaHJhc2UpIHtcbiAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcblxuICB2YXIgc2VjcmV0S2V5UGFja2V0ID0gbmV3IHBhY2tldC5zZWNyZXRfa2V5KCk7XG4gIHNlY3JldEtleVBhY2tldC5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwga2V5VHlwZSk7XG4gIHNlY3JldEtleVBhY2tldC5nZW5lcmF0ZShudW1CaXRzKTtcbiAgc2VjcmV0S2V5UGFja2V0LmVuY3J5cHQocGFzc3BocmFzZSk7XG5cbiAgdmFyIHVzZXJJZFBhY2tldCA9IG5ldyBwYWNrZXQudXNlcmlkKCk7XG4gIHVzZXJJZFBhY2tldC5yZWFkKHVzZXJJZCk7XG5cbiAgdmFyIGRhdGFUb1NpZ24gPSB7fTtcbiAgZGF0YVRvU2lnbi51c2VyaWQgPSB1c2VySWRQYWNrZXQ7XG4gIGRhdGFUb1NpZ24ua2V5ID0gc2VjcmV0S2V5UGFja2V0O1xuICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgc2lnbmF0dXJlUGFja2V0LnNpZ25hdHVyZVR5cGUgPSBlbnVtcy5zaWduYXR1cmUuY2VydF9nZW5lcmljO1xuICBzaWduYXR1cmVQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0ga2V5VHlwZTtcbiAgLy9UT0RPIHdlIHNob3VsZCBsb2FkIHByZWZlcnJlZCBoYXNoIGZyb20gY29uZmlnLCBvciBhcyBpbnB1dCB0byB0aGlzIGZ1bmN0aW9uXG4gIHNpZ25hdHVyZVBhY2tldC5oYXNoQWxnb3JpdGhtID0gZW51bXMuaGFzaC5zaGEyNTY7XG4gIHNpZ25hdHVyZVBhY2tldC5rZXlGbGFncyA9IFtlbnVtcy5rZXlGbGFncy5jZXJ0aWZ5X2tleXMgfCBlbnVtcy5rZXlGbGFncy5zaWduX2RhdGFdO1xuICBzaWduYXR1cmVQYWNrZXQuc2lnbihzZWNyZXRLZXlQYWNrZXQsIGRhdGFUb1NpZ24pO1xuXG4gIHZhciBzZWNyZXRTdWJrZXlQYWNrZXQgPSBuZXcgcGFja2V0LnNlY3JldF9zdWJrZXkoKTtcbiAgc2VjcmV0U3Via2V5UGFja2V0LmFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMucHVibGljS2V5LCBrZXlUeXBlKTtcbiAgc2VjcmV0U3Via2V5UGFja2V0LmdlbmVyYXRlKG51bUJpdHMpO1xuICBzZWNyZXRTdWJrZXlQYWNrZXQuZW5jcnlwdChwYXNzcGhyYXNlKTtcblxuICBkYXRhVG9TaWduID0ge307XG4gIGRhdGFUb1NpZ24ua2V5ID0gc2VjcmV0S2V5UGFja2V0O1xuICBkYXRhVG9TaWduLmJpbmQgPSBzZWNyZXRTdWJrZXlQYWNrZXQ7XG4gIHZhciBzdWJrZXlTaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQuc2lnbmF0dXJlVHlwZSA9IGVudW1zLnNpZ25hdHVyZS5zdWJrZXlfYmluZGluZztcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IGtleVR5cGU7XG4gIC8vVE9ETyB3ZSBzaG91bGQgbG9hZCBwcmVmZXJyZWQgaGFzaCBmcm9tIGNvbmZpZywgb3IgYXMgaW5wdXQgdG8gdGhpcyBmdW5jdGlvblxuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGVudW1zLmhhc2guc2hhMjU2O1xuICBzdWJrZXlTaWduYXR1cmVQYWNrZXQua2V5RmxhZ3MgPSBbZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9jb21tdW5pY2F0aW9uIHwgZW51bXMua2V5RmxhZ3MuZW5jcnlwdF9zdG9yYWdlXTtcbiAgc3Via2V5U2lnbmF0dXJlUGFja2V0LnNpZ24oc2VjcmV0S2V5UGFja2V0LCBkYXRhVG9TaWduKTtcblxuICBwYWNrZXRsaXN0LnB1c2goc2VjcmV0S2V5UGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHVzZXJJZFBhY2tldCk7XG4gIHBhY2tldGxpc3QucHVzaChzaWduYXR1cmVQYWNrZXQpO1xuICBwYWNrZXRsaXN0LnB1c2goc2VjcmV0U3Via2V5UGFja2V0KTtcbiAgcGFja2V0bGlzdC5wdXNoKHN1YmtleVNpZ25hdHVyZVBhY2tldCk7XG5cbiAgcmV0dXJuIG5ldyBLZXkocGFja2V0bGlzdCk7XG59XG5cbmV4cG9ydHMuS2V5ID0gS2V5O1xuZXhwb3J0cy5yZWFkQXJtb3JlZCA9IHJlYWRBcm1vcmVkO1xuZXhwb3J0cy5nZW5lcmF0ZSA9IGdlbmVyYXRlO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAcmVxdWlyZXMgY29uZmlnXG4gKiBAcmVxdWlyZXMgY3J5cHRvXG4gKiBAcmVxdWlyZXMgZW5jb2RpbmcvYXJtb3JcbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIHBhY2tldFxuICogQG1vZHVsZSBtZXNzYWdlXG4gKi9cblxudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0JyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpLFxuICBhcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKSxcbiAgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgQ2xhc3MgdGhhdCByZXByZXNlbnRzIGFuIE9wZW5QR1AgbWVzc2FnZS5cbiAqIENhbiBiZSBhbiBlbmNyeXB0ZWQgbWVzc2FnZSwgc2lnbmVkIG1lc3NhZ2UsIGNvbXByZXNzZWQgbWVzc2FnZSBvciBsaXRlcmFsIG1lc3NhZ2VcbiAqIEBwYXJhbSAge21vZHVsZTpwYWNrZXQvcGFja2V0bGlzdH0gcGFja2V0bGlzdCBUaGUgcGFja2V0cyB0aGF0IGZvcm0gdGhpcyBtZXNzYWdlXG4gKiBTZWUgaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg4MCNzZWN0aW9uLTExLjNcbiAqL1xuXG5mdW5jdGlvbiBNZXNzYWdlKHBhY2tldGxpc3QpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1lc3NhZ2UpKSB7XG4gICAgcmV0dXJuIG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xuICB9XG4gIHRoaXMucGFja2V0cyA9IHBhY2tldGxpc3QgfHwgbmV3IHBhY2tldC5saXN0KCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUga2V5IElEcyBvZiB0aGUga2V5cyB0byB3aGljaCB0aGUgc2Vzc2lvbiBrZXkgaXMgZW5jcnlwdGVkXG4gKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6dHlwZS9rZXlpZD59IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuZ2V0RW5jcnlwdGlvbktleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICBwa0VTS2V5UGFja2V0bGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgIGtleUlkcy5wdXNoKHBhY2tldC5wdWJsaWNLZXlJZCk7XG4gIH0pO1xuICByZXR1cm4ga2V5SWRzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBrZXkgSURzIG9mIHRoZSBrZXlzIHRoYXQgc2lnbmVkIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6dHlwZS9rZXlpZD59IGFycmF5IG9mIGtleWlkIG9iamVjdHNcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuZ2V0U2lnbmluZ0tleUlkcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIga2V5SWRzID0gW107XG4gIHZhciBtc2cgPSB0aGlzLnVud3JhcENvbXByZXNzZWQoKTtcbiAgLy8gc2VhcmNoIGZvciBvbmUgcGFzcyBzaWduYXR1cmVzXG4gIHZhciBvbmVQYXNzU2lnTGlzdCA9IG1zZy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5vbmVfcGFzc19zaWduYXR1cmUpO1xuICBvbmVQYXNzU2lnTGlzdC5mb3JFYWNoKGZ1bmN0aW9uKHBhY2tldCkge1xuICAgIGtleUlkcy5wdXNoKHBhY2tldC5zaWduaW5nS2V5SWQpO1xuICB9KTtcbiAgLy8gaWYgbm90aGluZyBmb3VuZCBsb29rIGZvciBzaWduYXR1cmUgcGFja2V0c1xuICBpZiAoIWtleUlkcy5sZW5ndGgpIHtcbiAgICB2YXIgc2lnbmF0dXJlTGlzdCA9IG1zZy5wYWNrZXRzLmZpbHRlckJ5VGFnKGVudW1zLnBhY2tldC5zaWduYXR1cmUpO1xuICAgIHNpZ25hdHVyZUxpc3QuZm9yRWFjaChmdW5jdGlvbihwYWNrZXQpIHtcbiAgICAgIGtleUlkcy5wdXNoKHBhY2tldC5pc3N1ZXJLZXlJZCk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGtleUlkcztcbn07XG5cbi8qKlxuICogRGVjcnlwdCB0aGUgbWVzc2FnZVxuICogQHBhcmFtIHttb2R1bGU6a2V5fktleX0gcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQgZGF0YSAgICAgICAgICAgXG4gKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6bWVzc2FnZX5NZXNzYWdlPn0gbmV3IG1lc3NhZ2Ugd2l0aCBkZWNyeXB0ZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSkge1xuICB2YXIgZW5jcnlwdGlvbktleUlkcyA9IHRoaXMuZ2V0RW5jcnlwdGlvbktleUlkcygpO1xuICBpZiAoIWVuY3J5cHRpb25LZXlJZHMubGVuZ3RoKSB7XG4gICAgLy8gbm90aGluZyB0byBkZWNyeXB0IHJldHVybiB1bm1vZGlmaWVkIG1lc3NhZ2VcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB2YXIgcHJpdmF0ZUtleVBhY2tldCA9IHByaXZhdGVLZXkuZ2V0UHJpdmF0ZUtleVBhY2tldChlbmNyeXB0aW9uS2V5SWRzKTtcbiAgaWYgKCFwcml2YXRlS2V5UGFja2V0LmlzRGVjcnlwdGVkKSB0aHJvdyBuZXcgRXJyb3IoJ1ByaXZhdGUga2V5IGlzIG5vdCBkZWNyeXB0ZWQuJyk7XG4gIHZhciBwa0VTS2V5UGFja2V0bGlzdCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQucHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkpO1xuICB2YXIgcGtFU0tleVBhY2tldDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwa0VTS2V5UGFja2V0bGlzdC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChwa0VTS2V5UGFja2V0bGlzdFtpXS5wdWJsaWNLZXlJZC5lcXVhbHMocHJpdmF0ZUtleVBhY2tldC5nZXRLZXlJZCgpKSkge1xuICAgICAgcGtFU0tleVBhY2tldCA9IHBrRVNLZXlQYWNrZXRsaXN0W2ldO1xuICAgICAgcGtFU0tleVBhY2tldC5kZWNyeXB0KHByaXZhdGVLZXlQYWNrZXQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChwa0VTS2V5UGFja2V0KSB7XG4gICAgdmFyIHN5bUVuY3J5cHRlZFBhY2tldGxpc3QgPSB0aGlzLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLCBlbnVtcy5wYWNrZXQuc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKTtcbiAgICBpZiAoc3ltRW5jcnlwdGVkUGFja2V0bGlzdC5sZW5ndGggIT09IDApIHtcbiAgICAgIHZhciBzeW1FbmNyeXB0ZWRQYWNrZXQgPSBzeW1FbmNyeXB0ZWRQYWNrZXRsaXN0WzBdO1xuICAgICAgc3ltRW5jcnlwdGVkUGFja2V0LmRlY3J5cHQocGtFU0tleVBhY2tldC5zZXNzaW9uS2V5QWxnb3JpdGhtLCBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXkpO1xuICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlKHN5bUVuY3J5cHRlZFBhY2tldC5wYWNrZXRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGxpdGVyYWwgZGF0YSB0aGF0IGlzIHRoZSBib2R5IG9mIHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHsoU3RyaW5nfG51bGwpfSBsaXRlcmFsIGJvZHkgb2YgdGhlIG1lc3NhZ2UgYXMgc3RyaW5nXG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLmdldExpdGVyYWxEYXRhID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsaXRlcmFsID0gdGhpcy5wYWNrZXRzLmZpbmRQYWNrZXQoZW51bXMucGFja2V0LmxpdGVyYWwpO1xuICByZXR1cm4gbGl0ZXJhbCAmJiBsaXRlcmFsLmRhdGEgfHwgbnVsbDtcbn07XG5cbi8qKlxuICogR2V0IGxpdGVyYWwgZGF0YSBhcyB0ZXh0XG4gKiBAcmV0dXJuIHsoU3RyaW5nfG51bGwpfSBsaXRlcmFsIGJvZHkgb2YgdGhlIG1lc3NhZ2UgaW50ZXJwcmV0ZWQgYXMgdGV4dFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5nZXRUZXh0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsaXRlcmFsID0gdGhpcy5wYWNrZXRzLmZpbmRQYWNrZXQoZW51bXMucGFja2V0LmxpdGVyYWwpO1xuICBpZiAobGl0ZXJhbCkge1xuICAgIHJldHVybiBsaXRlcmFsLmdldFRleHQoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufTtcblxuLyoqXG4gKiBFbmNyeXB0IHRoZSBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59IGtleXMgYXJyYXkgb2Yga2V5cywgdXNlZCB0byBlbmNyeXB0IHRoZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtBcnJheTxtb2R1bGU6bWVzc2FnZX5NZXNzYWdlPn0gbmV3IG1lc3NhZ2Ugd2l0aCBlbmNyeXB0ZWQgY29udGVudFxuICovXG5NZXNzYWdlLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oa2V5cykge1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBhbGdvIGZyb20gc2lnbmF0dXJlXG4gIHZhciBzZXNzaW9uS2V5ID0gY3J5cHRvLmdlbmVyYXRlU2Vzc2lvbktleShlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyKSk7XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZW5jcnlwdGlvbktleVBhY2tldCA9IGtleS5nZXRFbmNyeXB0aW9uS2V5UGFja2V0KCk7XG4gICAgaWYgKGVuY3J5cHRpb25LZXlQYWNrZXQpIHtcbiAgICAgIHZhciBwa0VTS2V5UGFja2V0ID0gbmV3IHBhY2tldC5wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSgpO1xuICAgICAgcGtFU0tleVBhY2tldC5wdWJsaWNLZXlJZCA9IGVuY3J5cHRpb25LZXlQYWNrZXQuZ2V0S2V5SWQoKTtcbiAgICAgIHBrRVNLZXlQYWNrZXQucHVibGljS2V5QWxnb3JpdGhtID0gZW5jcnlwdGlvbktleVBhY2tldC5hbGdvcml0aG07XG4gICAgICBwa0VTS2V5UGFja2V0LnNlc3Npb25LZXkgPSBzZXNzaW9uS2V5O1xuICAgICAgLy9UT0RPIGdldCBwcmVmZXJyZWQgYWxnbyBmcm9tIHNpZ25hdHVyZVxuICAgICAgcGtFU0tleVBhY2tldC5zZXNzaW9uS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7XG4gICAgICBwa0VTS2V5UGFja2V0LmVuY3J5cHQoZW5jcnlwdGlvbktleVBhY2tldCk7XG4gICAgICBwYWNrZXRsaXN0LnB1c2gocGtFU0tleVBhY2tldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgdmFsaWQga2V5IHBhY2tldCBmb3IgZW5jcnlwdGlvbiBpbiBrZXkgJyArIGtleS5wcmltYXJ5S2V5LmdldEtleUlkKCkudG9IZXgoKSk7XG4gICAgfVxuICB9KTtcbiAgdmFyIHN5bUVuY3J5cHRlZFBhY2tldDtcbiAgaWYgKGNvbmZpZy5pbnRlZ3JpdHlfcHJvdGVjdCkge1xuICAgIHN5bUVuY3J5cHRlZFBhY2tldCA9IG5ldyBwYWNrZXQuc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCk7XG4gIH0gZWxzZSB7XG4gICAgc3ltRW5jcnlwdGVkUGFja2V0ID0gbmV3IHBhY2tldC5zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZCgpO1xuICB9XG4gIHN5bUVuY3J5cHRlZFBhY2tldC5wYWNrZXRzID0gdGhpcy5wYWNrZXRzO1xuICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBhbGdvIGZyb20gc2lnbmF0dXJlXG4gIHN5bUVuY3J5cHRlZFBhY2tldC5lbmNyeXB0KGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBjb25maWcuZW5jcnlwdGlvbl9jaXBoZXIpLCBzZXNzaW9uS2V5KTtcbiAgcGFja2V0bGlzdC5wdXNoKHN5bUVuY3J5cHRlZFBhY2tldCk7XG4gIHJldHVybiBuZXcgTWVzc2FnZShwYWNrZXRsaXN0KTtcbn07XG5cbi8qKlxuICogU2lnbiB0aGUgbWVzc2FnZSAodGhlIGxpdGVyYWwgZGF0YSBwYWNrZXQgb2YgdGhlIG1lc3NhZ2UpXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHByaXZhdGVLZXkgcHJpdmF0ZSBrZXlzIHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YSBmb3Igc2lnbmluZ1xuICogQHJldHVybiB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gICAgICBuZXcgbWVzc2FnZSB3aXRoIHNpZ25lZCBjb250ZW50XG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbihwcml2YXRlS2V5cykge1xuXG4gIHZhciBwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG5cbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gdGhpcy5wYWNrZXRzLmZpbmRQYWNrZXQoZW51bXMucGFja2V0LmxpdGVyYWwpO1xuICBpZiAoIWxpdGVyYWxEYXRhUGFja2V0KSB0aHJvdyBuZXcgRXJyb3IoJ05vIGxpdGVyYWwgZGF0YSBwYWNrZXQgdG8gc2lnbi4nKTtcbiAgXG4gIHZhciBsaXRlcmFsRm9ybWF0ID0gZW51bXMud3JpdGUoZW51bXMubGl0ZXJhbCwgbGl0ZXJhbERhdGFQYWNrZXQuZm9ybWF0KTtcbiAgdmFyIHNpZ25hdHVyZVR5cGUgPSBsaXRlcmFsRm9ybWF0ID09IGVudW1zLmxpdGVyYWwuYmluYXJ5IFxuICAgICAgICAgICAgICAgICAgICAgID8gZW51bXMuc2lnbmF0dXJlLmJpbmFyeSA6IGVudW1zLnNpZ25hdHVyZS50ZXh0OyBcbiAgXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJpdmF0ZUtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgb25lUGFzc1NpZyA9IG5ldyBwYWNrZXQub25lX3Bhc3Nfc2lnbmF0dXJlKCk7XG4gICAgb25lUGFzc1NpZy50eXBlID0gc2lnbmF0dXJlVHlwZTtcbiAgICAvL1RPRE8gZ2V0IHByZWZlcnJlZCBoYXNoZyBhbGdvIGZyb20ga2V5IHNpZ25hdHVyZVxuICAgIG9uZVBhc3NTaWcuaGFzaEFsZ29yaXRobSA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgdmFyIHNpZ25pbmdLZXlQYWNrZXQgPSBwcml2YXRlS2V5c1tpXS5nZXRTaWduaW5nS2V5UGFja2V0KCk7XG4gICAgaWYgKCFzaWduaW5nS2V5UGFja2V0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHZhbGlkIGtleSBwYWNrZXQgZm9yIHNpZ25pbmcgaW4ga2V5ICcgKyBwcml2YXRlS2V5c1tpXS5wcmltYXJ5S2V5LmdldEtleUlkKCkudG9IZXgoKSk7XG4gICAgfVxuICAgIG9uZVBhc3NTaWcucHVibGljS2V5QWxnb3JpdGhtID0gc2lnbmluZ0tleVBhY2tldC5hbGdvcml0aG07XG4gICAgb25lUGFzc1NpZy5zaWduaW5nS2V5SWQgPSBzaWduaW5nS2V5UGFja2V0LmdldEtleUlkKCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKG9uZVBhc3NTaWcpO1xuICB9XG5cbiAgcGFja2V0bGlzdC5wdXNoKGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgXG4gIGZvciAodmFyIGkgPSBwcml2YXRlS2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBzaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduYXR1cmVUeXBlID0gc2lnbmF0dXJlVHlwZTtcbiAgICBzaWduYXR1cmVQYWNrZXQuaGFzaEFsZ29yaXRobSA9IGNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG07XG4gICAgc2lnbmF0dXJlUGFja2V0LnB1YmxpY0tleUFsZ29yaXRobSA9IHNpZ25pbmdLZXlQYWNrZXQuYWxnb3JpdGhtO1xuICAgIGlmICghc2lnbmluZ0tleVBhY2tldC5pc0RlY3J5cHRlZCkgdGhyb3cgbmV3IEVycm9yKCdQcml2YXRlIGtleSBpcyBub3QgZGVjcnlwdGVkLicpO1xuICAgIHNpZ25hdHVyZVBhY2tldC5zaWduKHNpZ25pbmdLZXlQYWNrZXQsIGxpdGVyYWxEYXRhUGFja2V0KTtcbiAgICBwYWNrZXRsaXN0LnB1c2goc2lnbmF0dXJlUGFja2V0KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTWVzc2FnZShwYWNrZXRsaXN0KTtcbn07XG5cbi8qKlxuICogVmVyaWZ5IG1lc3NhZ2Ugc2lnbmF0dXJlc1xuICogQHBhcmFtIHtBcnJheTxtb2R1bGU6a2V5fktleT59IHB1YmxpY0tleXMgcHVibGljIGtleXMgdG8gdmVyaWZ5IHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge0FycmF5PCh7a2V5aWQ6IG1vZHVsZTp0eXBlL2tleWlkLCB2YWxpZDogQm9vbGVhbn0pPn0gbGlzdCBvZiBzaWduZXIncyBrZXlpZCBhbmQgdmFsaWRpdHkgb2Ygc2lnbmF0dXJlXG4gKi9cbk1lc3NhZ2UucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uKHB1YmxpY0tleXMpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgbXNnID0gdGhpcy51bndyYXBDb21wcmVzc2VkKCk7XG4gIHZhciBsaXRlcmFsRGF0YUxpc3QgPSBtc2cucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQubGl0ZXJhbCk7XG4gIGlmIChsaXRlcmFsRGF0YUxpc3QubGVuZ3RoICE9PSAxKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBvbmx5IHZlcmlmeSBtZXNzYWdlIHdpdGggb25lIGxpdGVyYWwgZGF0YSBwYWNrZXQuJyk7XG4gIHZhciBzaWduYXR1cmVMaXN0ID0gbXNnLnBhY2tldHMuZmlsdGVyQnlUYWcoZW51bXMucGFja2V0LnNpZ25hdHVyZSk7XG4gIHB1YmxpY0tleXMuZm9yRWFjaChmdW5jdGlvbihwdWJLZXkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ25hdHVyZUxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwdWJsaWNLZXlQYWNrZXQgPSBwdWJLZXkuZ2V0UHVibGljS2V5UGFja2V0KFtzaWduYXR1cmVMaXN0W2ldLmlzc3VlcktleUlkXSk7XG4gICAgICBpZiAocHVibGljS2V5UGFja2V0KSB7XG4gICAgICAgIHZhciB2ZXJpZmllZFNpZyA9IHt9O1xuICAgICAgICB2ZXJpZmllZFNpZy5rZXlpZCA9IHNpZ25hdHVyZUxpc3RbaV0uaXNzdWVyS2V5SWQ7XG4gICAgICAgIHZlcmlmaWVkU2lnLnZhbGlkID0gc2lnbmF0dXJlTGlzdFtpXS52ZXJpZnkocHVibGljS2V5UGFja2V0LCBsaXRlcmFsRGF0YUxpc3RbMF0pO1xuICAgICAgICByZXN1bHQucHVzaCh2ZXJpZmllZFNpZyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIFVud3JhcCBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge21vZHVsZTptZXNzYWdlfk1lc3NhZ2V9IG1lc3NhZ2UgQ29udGVudCBvZiBjb21wcmVzc2VkIG1lc3NhZ2VcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUudW53cmFwQ29tcHJlc3NlZCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29tcHJlc3NlZCA9IHRoaXMucGFja2V0cy5maWx0ZXJCeVRhZyhlbnVtcy5wYWNrZXQuY29tcHJlc3NlZCk7XG4gIGlmIChjb21wcmVzc2VkLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgTWVzc2FnZShjb21wcmVzc2VkWzBdLnBhY2tldHMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgQVNDSUkgYXJtb3JlZCB0ZXh0IG9mIG1lc3NhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ30gQVNDSUkgYXJtb3JcbiAqL1xuTWVzc2FnZS5wcm90b3R5cGUuYXJtb3IgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCB0aGlzLnBhY2tldHMud3JpdGUoKSk7XG59O1xuXG4vKipcbiAqIHJlYWRzIGFuIE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlIGFuZCByZXR1cm5zIGEgbWVzc2FnZSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuICogQHJldHVybiB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKiBAc3RhdGljXG4gKi9cbmZ1bmN0aW9uIHJlYWRBcm1vcmVkKGFybW9yZWRUZXh0KSB7XG4gIC8vVE9ETyBob3cgZG8gd2Ugd2FudCB0byBoYW5kbGUgYmFkIHRleHQ/IEV4Y2VwdGlvbiB0aHJvd2luZ1xuICAvL1RPRE8gZG9uJ3QgYWNjZXB0IG5vbi1tZXNzYWdlIGFybW9yZWQgdGV4dHNcbiAgdmFyIGlucHV0ID0gYXJtb3IuZGVjb2RlKGFybW9yZWRUZXh0KS5kYXRhO1xuICB2YXIgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICBwYWNrZXRsaXN0LnJlYWQoaW5wdXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKHBhY2tldGxpc3QpO1xuICByZXR1cm4gbmV3TWVzc2FnZTtcbn1cblxuLyoqXG4gKiBjcmVhdGVzIG5ldyBtZXNzYWdlIG9iamVjdCBmcm9tIHRleHRcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0XG4gKiBAcmV0dXJuIHttb2R1bGU6bWVzc2FnZX5NZXNzYWdlfSBuZXcgbWVzc2FnZSBvYmplY3RcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gZnJvbVRleHQodGV4dCkge1xuICB2YXIgbGl0ZXJhbERhdGFQYWNrZXQgPSBuZXcgcGFja2V0LmxpdGVyYWwoKTtcbiAgLy8gdGV4dCB3aWxsIGJlIGNvbnZlcnRlZCB0byBVVEY4XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldFRleHQodGV4dCk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG4vKipcbiAqIGNyZWF0ZXMgbmV3IG1lc3NhZ2Ugb2JqZWN0IGZyb20gYmluYXJ5IGRhdGFcbiAqIEBwYXJhbSB7U3RyaW5nfSBieXRlc1xuICogQHJldHVybiB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gbmV3IG1lc3NhZ2Ugb2JqZWN0XG4gKiBAc3RhdGljXG4gKi9cbmZ1bmN0aW9uIGZyb21CaW5hcnkoYnl0ZXMpIHtcbiAgdmFyIGxpdGVyYWxEYXRhUGFja2V0ID0gbmV3IHBhY2tldC5saXRlcmFsKCk7XG4gIGxpdGVyYWxEYXRhUGFja2V0LnNldEJ5dGVzKGJ5dGVzLCBlbnVtcy5yZWFkKGVudW1zLmxpdGVyYWwsIGVudW1zLmxpdGVyYWwuYmluYXJ5KSk7XG4gIHZhciBsaXRlcmFsRGF0YVBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgbGl0ZXJhbERhdGFQYWNrZXRsaXN0LnB1c2gobGl0ZXJhbERhdGFQYWNrZXQpO1xuICB2YXIgbmV3TWVzc2FnZSA9IG5ldyBNZXNzYWdlKGxpdGVyYWxEYXRhUGFja2V0bGlzdCk7XG4gIHJldHVybiBuZXdNZXNzYWdlO1xufVxuXG5leHBvcnRzLk1lc3NhZ2UgPSBNZXNzYWdlO1xuZXhwb3J0cy5yZWFkQXJtb3JlZCA9IHJlYWRBcm1vcmVkO1xuZXhwb3J0cy5mcm9tVGV4dCA9IGZyb21UZXh0O1xuZXhwb3J0cy5mcm9tQmluYXJ5ID0gZnJvbUJpbmFyeTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBUaGUgb3BlbnBncCBiYXNlIG1vZHVsZSBzaG91bGQgcHJvdmlkZSBhbGwgb2YgdGhlIGZ1bmN0aW9uYWxpdHkgXG4gKiB0byBjb25zdW1lIHRoZSBvcGVucGdwLmpzIGxpYnJhcnkuIEFsbCBhZGRpdGlvbmFsIGNsYXNzZXMgYXJlIGRvY3VtZW50ZWQgXG4gKiBmb3IgZXh0ZW5kaW5nIGFuZCBkZXZlbG9waW5nIG9uIHRvcCBvZiB0aGUgYmFzZSBsaWJyYXJ5LlxuICovXG5cbi8qKlxuICogQHJlcXVpcmVzIGNsZWFydGV4dFxuICogQHJlcXVpcmVzIGNvbmZpZ1xuICogQHJlcXVpcmVzIGVuY29kaW5nL2FybW9yXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyBtZXNzYWdlXG4gKiBAcmVxdWlyZXMgcGFja2V0XG4gKiBAbW9kdWxlIG9wZW5wZ3BcbiAqL1xuXG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyksXG4gIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0JyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpLFxuICBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpLFxuICBtZXNzYWdlID0gcmVxdWlyZSgnLi9tZXNzYWdlLmpzJyksXG4gIGNsZWFydGV4dCA9IHJlcXVpcmUoJy4vY2xlYXJ0ZXh0LmpzJyksXG4gIGtleSA9IHJlcXVpcmUoJy4va2V5LmpzJyk7XG5cblxuLyoqXG4gKiBFbmNyeXB0cyBtZXNzYWdlIHRleHQgd2l0aCBrZXlzXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICBrZXlzIGFycmF5IG9mIGtleXMsIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZVxuICogQHBhcmFtICB7U3RyaW5nfSB0ZXh0IG1lc3NhZ2UgYXMgbmF0aXZlIEphdmFTY3JpcHQgc3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgZW5jcnlwdGVkIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICogQHN0YXRpY1xuICovXG5mdW5jdGlvbiBlbmNyeXB0TWVzc2FnZShrZXlzLCB0ZXh0KSB7XG4gIHZhciBtc2cgPSBtZXNzYWdlLmZyb21UZXh0KHRleHQpO1xuICBtc2cgPSBtc2cuZW5jcnlwdChrZXlzKTtcbiAgdmFyIGFybW9yZWQgPSBhcm1vci5lbmNvZGUoZW51bXMuYXJtb3IubWVzc2FnZSwgbXNnLnBhY2tldHMud3JpdGUoKSk7XG4gIHJldHVybiBhcm1vcmVkO1xufVxuXG4vKipcbiAqIFNpZ25zIG1lc3NhZ2UgdGV4dCBhbmQgZW5jcnlwdHMgaXRcbiAqIEBwYXJhbSAge0FycmF5PG1vZHVsZTprZXl+S2V5Pn0gIHB1YmxpY0tleXMgYXJyYXkgb2Yga2V5cywgdXNlZCB0byBlbmNyeXB0IHRoZSBtZXNzYWdlXG4gKiBAcGFyYW0gIHttb2R1bGU6a2V5fktleX0gICAgcHJpdmF0ZUtleSBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgZm9yIHNpZ25pbmdcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICBtZXNzYWdlIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSAgICAgICAgICAgIGVuY3J5cHRlZCBBU0NJSSBhcm1vcmVkIG1lc3NhZ2VcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gc2lnbkFuZEVuY3J5cHRNZXNzYWdlKHB1YmxpY0tleXMsIHByaXZhdGVLZXksIHRleHQpIHtcbiAgdmFyIG1zZyA9IG1lc3NhZ2UuZnJvbVRleHQodGV4dCk7XG4gIG1zZyA9IG1zZy5zaWduKFtwcml2YXRlS2V5XSk7XG4gIG1zZyA9IG1zZy5lbmNyeXB0KHB1YmxpY0tleXMpO1xuICB2YXIgYXJtb3JlZCA9IGFybW9yLmVuY29kZShlbnVtcy5hcm1vci5tZXNzYWdlLCBtc2cucGFja2V0cy53cml0ZSgpKTtcbiAgcmV0dXJuIGFybW9yZWQ7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZVxuICogQHBhcmFtICB7bW9kdWxlOmtleX5LZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7bW9kdWxlOm1lc3NhZ2V+TWVzc2FnZX0gbWVzc2FnZSAgICB0aGUgbWVzc2FnZSBvYmplY3Qgd2l0aCB0aGUgZW5jcnlwdGVkIGRhdGFcbiAqIEByZXR1cm4geyhTdHJpbmd8bnVsbCl9ICAgICAgICBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3IgbnVsbCBpZiBubyBsaXRlcmFsIGRhdGEgZm91bmRcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gZGVjcnlwdE1lc3NhZ2UocHJpdmF0ZUtleSwgbWVzc2FnZSkge1xuICBtZXNzYWdlID0gbWVzc2FnZS5kZWNyeXB0KHByaXZhdGVLZXkpO1xuICByZXR1cm4gbWVzc2FnZS5nZXRUZXh0KCk7XG59XG5cbi8qKlxuICogRGVjcnlwdHMgbWVzc2FnZSBhbmQgdmVyaWZpZXMgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bW9kdWxlOmtleX5LZXl9ICAgICBwcml2YXRlS2V5IHByaXZhdGUga2V5IHdpdGggZGVjcnlwdGVkIHNlY3JldCBrZXkgZGF0YVxuICogQHBhcmFtICB7QXJyYXk8bW9kdWxlOmtleX5LZXk+fSAgIHB1YmxpY0tleXMgcHVibGljIGtleXMgdG8gdmVyaWZ5IHNpZ25hdHVyZXNcbiAqIEBwYXJhbSAge21vZHVsZTptZXNzYWdlfk1lc3NhZ2V9IG1lc3NhZ2UgICAgdGhlIG1lc3NhZ2Ugb2JqZWN0IHdpdGggc2lnbmVkIGFuZCBlbmNyeXB0ZWQgZGF0YVxuICogQHJldHVybiB7e3RleHQ6IFN0cmluZywgc2lnbmF0dXJlczogQXJyYXk8e2tleWlkOiBtb2R1bGU6dHlwZS9rZXlpZCwgdmFsaWQ6IEJvb2xlYW59Pn19XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZCBtZXNzYWdlIGFzIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHZlcmlmaWVkIHNpZ25hdHVyZXMgb3IgbnVsbCBpZiBubyBsaXRlcmFsIGRhdGEgZm91bmRcbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2UocHJpdmF0ZUtleSwgcHVibGljS2V5cywgbWVzc2FnZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIG1lc3NhZ2UgPSBtZXNzYWdlLmRlY3J5cHQocHJpdmF0ZUtleSk7XG4gIHJlc3VsdC50ZXh0ID0gbWVzc2FnZS5nZXRUZXh0KCk7XG4gIGlmIChyZXN1bHQudGV4dCkge1xuICAgIHJlc3VsdC5zaWduYXR1cmVzID0gbWVzc2FnZS52ZXJpZnkocHVibGljS2V5cyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBTaWducyBhIGNsZWFydGV4dCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICBwcml2YXRlS2V5cyBwcml2YXRlIGtleSB3aXRoIGRlY3J5cHRlZCBzZWNyZXQga2V5IGRhdGEgdG8gc2lnbiBjbGVhcnRleHRcbiAqIEBwYXJhbSAge1N0cmluZ30gdGV4dCAgICAgICAgY2xlYXJ0ZXh0XG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICAgICAgICAgIEFTQ0lJIGFybW9yZWQgbWVzc2FnZVxuICogQHN0YXRpY1xuICovXG5mdW5jdGlvbiBzaWduQ2xlYXJNZXNzYWdlKHByaXZhdGVLZXlzLCB0ZXh0KSB7XG4gIHZhciBjbGVhcnRleHRNZXNzYWdlID0gbmV3IGNsZWFydGV4dC5DbGVhcnRleHRNZXNzYWdlKHRleHQpO1xuICBjbGVhcnRleHRNZXNzYWdlLnNpZ24ocHJpdmF0ZUtleXMpO1xuICByZXR1cm4gY2xlYXJ0ZXh0TWVzc2FnZS5hcm1vcigpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIHNpZ25hdHVyZXMgb2YgY2xlYXJ0ZXh0IHNpZ25lZCBtZXNzYWdlXG4gKiBAcGFyYW0gIHtBcnJheTxtb2R1bGU6a2V5fktleT59ICAgICAgICAgICAgcHVibGljS2V5cyBwdWJsaWMga2V5cyB0byB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHBhcmFtICB7bW9kdWxlOmNsZWFydGV4dH5DbGVhcnRleHRNZXNzYWdlfSBtZXNzYWdlICAgIGNsZWFydGV4dCBtZXNzYWdlIG9iamVjdCB3aXRoIHNpZ25hdHVyZXNcbiAqIEByZXR1cm4ge3t0ZXh0OiBTdHJpbmcsIHNpZ25hdHVyZXM6IEFycmF5PHtrZXlpZDogbW9kdWxlOnR5cGUva2V5aWQsIHZhbGlkOiBCb29sZWFufT59fVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhcnRleHQgd2l0aCBzdGF0dXMgb2YgdmVyaWZpZWQgc2lnbmF0dXJlc1xuICogQHN0YXRpY1xuICovXG5mdW5jdGlvbiB2ZXJpZnlDbGVhclNpZ25lZE1lc3NhZ2UocHVibGljS2V5cywgbWVzc2FnZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGlmICghKG1lc3NhZ2UgaW5zdGFuY2VvZiBjbGVhcnRleHQuQ2xlYXJ0ZXh0TWVzc2FnZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciBbbWVzc2FnZV0gbmVlZHMgdG8gYmUgb2YgdHlwZSBDbGVhcnRleHRNZXNzYWdlLicpO1xuICB9XG4gIHJlc3VsdC50ZXh0ID0gbWVzc2FnZS5nZXRUZXh0KCk7XG4gIHJlc3VsdC5zaWduYXR1cmVzID0gbWVzc2FnZS52ZXJpZnkocHVibGljS2V5cyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgbmV3IE9wZW5QR1Aga2V5IHBhaXIuIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIFJTQSBrZXlzLlxuICogUHJpbWFyeSBhbmQgc3Via2V5IHdpbGwgYmUgb2Ygc2FtZSB0eXBlLlxuICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlICAgIHRvIGluZGljYXRlIHdoYXQgdHlwZSBvZiBrZXkgdG8gbWFrZS4gXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlNBIGlzIDEuIFNlZSBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODgwI3NlY3Rpb24tOS4xXG4gKiBAcGFyYW0ge0ludGVnZXJ9IG51bUJpdHMgICAgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBrZXkgY3JlYXRpb24uIChzaG91bGQgYmUgMTAyNCssIGdlbmVyYWxseSlcbiAqIEBwYXJhbSB7U3RyaW5nfSAgdXNlcklkICAgICBhc3N1bWVzIGFscmVhZHkgaW4gZm9ybSBvZiBcIlVzZXIgTmFtZSA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gKiBAcGFyYW0ge1N0cmluZ30gIHBhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBlbmNyeXB0IHRoZSByZXN1bHRpbmcgcHJpdmF0ZSBrZXlcbiAqIEByZXR1cm4ge09iamVjdH0ge2tleTogQXJyYXk8bW9kdWxlOmtleX5LZXk+LCBwcml2YXRlS2V5QXJtb3JlZDogQXJyYXk8U3RyaW5nPiwgcHVibGljS2V5QXJtb3JlZDogQXJyYXk8U3RyaW5nPn1cbiAqIEBzdGF0aWNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKGtleVR5cGUsIG51bUJpdHMsIHVzZXJJZCwgcGFzc3BocmFzZSkge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBuZXdLZXkgPSBrZXkuZ2VuZXJhdGUoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKTtcbiAgcmVzdWx0LmtleSA9IG5ld0tleTtcbiAgcmVzdWx0LnByaXZhdGVLZXlBcm1vcmVkID0gbmV3S2V5LmFybW9yKCk7XG4gIHJlc3VsdC5wdWJsaWNLZXlBcm1vcmVkID0gbmV3S2V5LnRvUHVibGljKCkuYXJtb3IoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5lbmNyeXB0TWVzc2FnZSA9IGVuY3J5cHRNZXNzYWdlO1xuZXhwb3J0cy5zaWduQW5kRW5jcnlwdE1lc3NhZ2UgPSBzaWduQW5kRW5jcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRNZXNzYWdlID0gZGVjcnlwdE1lc3NhZ2U7XG5leHBvcnRzLmRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlID0gZGVjcnlwdEFuZFZlcmlmeU1lc3NhZ2VcbmV4cG9ydHMuc2lnbkNsZWFyTWVzc2FnZSA9IHNpZ25DbGVhck1lc3NhZ2U7XG5leHBvcnRzLnZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZSA9IHZlcmlmeUNsZWFyU2lnbmVkTWVzc2FnZTtcbmV4cG9ydHMuZ2VuZXJhdGVLZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyO1xuIiwiLyoqXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEBtb2R1bGUgcGFja2V0XG4gKi9cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8vIFRoaXMgaXMgcHJldHR5IHVnbHksIGJ1dCBicm93c2VyaWZ5IG5lZWRzIHRvIGhhdmUgdGhlIHJlcXVpcmVzIGV4cGxpY2l0bHkgd3JpdHRlbi5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvY29tcHJlc3NlZCAqL1xuICBjb21wcmVzc2VkOiByZXF1aXJlKCcuL2NvbXByZXNzZWQuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOnBhY2tldC9zeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQgKi9cbiAgc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkOiByZXF1aXJlKCcuL3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZC5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6cGFja2V0L3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5ICovXG4gIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleSAqL1xuICBzeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOnBhY2tldC9saXRlcmFsICovXG4gIGxpdGVyYWw6IHJlcXVpcmUoJy4vbGl0ZXJhbC5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6cGFja2V0L3B1YmxpY19rZXkgKi9cbiAgcHVibGljX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQgKi9cbiAgc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQ6IHJlcXVpcmUoJy4vc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOnBhY2tldC9tYXJrZXIgKi9cbiAgbWFya2VyOiByZXF1aXJlKCcuL21hcmtlci5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6cGFja2V0L3B1YmxpY19zdWJrZXkgKi9cbiAgcHVibGljX3N1YmtleTogcmVxdWlyZSgnLi9wdWJsaWNfc3Via2V5LmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvdXNlcl9hdHRyaWJ1dGUgKi9cbiAgdXNlcl9hdHRyaWJ1dGU6IHJlcXVpcmUoJy4vdXNlcl9hdHRyaWJ1dGUuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOnBhY2tldC9vbmVfcGFzc19zaWduYXR1cmUgKi9cbiAgb25lX3Bhc3Nfc2lnbmF0dXJlOiByZXF1aXJlKCcuL29uZV9wYXNzX3NpZ25hdHVyZS5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6cGFja2V0L3NlY3JldF9rZXkgKi9cbiAgc2VjcmV0X2tleTogcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvdXNlcmlkICovXG4gIHVzZXJpZDogcmVxdWlyZSgnLi91c2VyaWQuanMnKSxcbiAgLyoqIEBzZWUgbW9kdWxlOnBhY2tldC9zZWNyZXRfc3Via2V5ICovXG4gIHNlY3JldF9zdWJrZXk6IHJlcXVpcmUoJy4vc2VjcmV0X3N1YmtleS5qcycpLFxuICAvKiogQHNlZSBtb2R1bGU6cGFja2V0L3NpZ25hdHVyZSAqL1xuICBzaWduYXR1cmU6IHJlcXVpcmUoJy4vc2lnbmF0dXJlLmpzJyksXG4gIC8qKiBAc2VlIG1vZHVsZTpwYWNrZXQvdHJ1c3QgKi9cbiAgdHJ1c3Q6IHJlcXVpcmUoJy4vdHJ1c3QuanMnKVxufVxuXG5mb3IgKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuICB2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuICBpZiAocGFja2V0Q2xhc3MgIT0gdW5kZWZpbmVkKVxuICAgIHBhY2tldENsYXNzLnByb3RvdHlwZS50YWcgPSBlbnVtcy5wYWNrZXRbaV07XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBDb21wcmVzc2VkIERhdGEgUGFja2V0IChUYWcgOCk8YnIvPlxuICogPGJyLz5cbiAqIFJGQzQ4ODAgNS42OiBUaGUgQ29tcHJlc3NlZCBEYXRhIHBhY2tldCBjb250YWlucyBjb21wcmVzc2VkIGRhdGEuICBUeXBpY2FsbHksXG4gKiB0aGlzIHBhY2tldCBpcyBmb3VuZCBhcyB0aGUgY29udGVudHMgb2YgYW4gZW5jcnlwdGVkIHBhY2tldCwgb3IgZm9sbG93aW5nXG4gKiBhIFNpZ25hdHVyZSBvciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0LCBhbmQgY29udGFpbnMgYSBsaXRlcmFsIGRhdGEgcGFja2V0LlxuICogQHJlcXVpcmVzIGNvbXByZXNzaW9uL2p4Z1xuICogQHJlcXVpcmVzIGVuY29kaW5nL2Jhc2U2NFxuICogQHJlcXVpcmVzIGVudW1zXG4gKiBAbW9kdWxlIHBhY2tldC9jb21wcmVzc2VkXG4gKi9cblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgSlhHID0gcmVxdWlyZSgnLi4vY29tcHJlc3Npb24vanhnLmpzJyksXG4gIGJhc2U2NCA9IHJlcXVpcmUoJy4uL2VuY29kaW5nL2Jhc2U2NC5qcycpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIExpc3Qgb2YgcGFja2V0c1xuICAgKiBAdHlwZSB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fVxuICAgKi9cbiAgdGhpcy5wYWNrZXRzID0gbnVsbDtcbiAgLyoqXG4gICAqIENvbXByZXNzaW9uIGFsZ29yaXRobVxuICAgKiBAdHlwZSB7Y29tcHJlc3Npb259XG4gICAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICd1bmNvbXByZXNzZWQnO1xuXG4gIC8qKlxuICAgKiBDb21wcmVzc2VkIHBhY2tldCBkYXRhXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICB0aGlzLmNvbXByZXNzZWQgPSBudWxsO1xuXG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIHRoZSBwYWNrZXQuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBQYXlsb2FkIG9mIGEgdGFnIDggcGFja2V0XG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIE9uZSBvY3RldCB0aGF0IGdpdmVzIHRoZSBhbGdvcml0aG0gdXNlZCB0byBjb21wcmVzcyB0aGUgcGFja2V0LlxuICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5jb21wcmVzc2lvbiwgYnl0ZXMuY2hhckNvZGVBdCgwKSk7XG5cbiAgICAvLyBDb21wcmVzc2VkIGRhdGEsIHdoaWNoIG1ha2VzIHVwIHRoZSByZW1haW5kZXIgb2YgdGhlIHBhY2tldC5cbiAgICB0aGlzLmNvbXByZXNzZWQgPSBieXRlcy5zdWJzdHIoMSk7XG5cbiAgICB0aGlzLmRlY29tcHJlc3MoKTtcbiAgfVxuXG5cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBjb21wcmVzc2VkIHBhY2tldC5cbiAgICogQHJldHVybiB7U3RyaW5nfSBiaW5hcnkgY29tcHJlc3NlZCBwYWNrZXRcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5jb21wcmVzc2VkID09IG51bGwpXG4gICAgICB0aGlzLmNvbXByZXNzKCk7XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5jb21wcmVzc2lvbiwgdGhpcy5hbGdvcml0aG0pKSArIHRoaXMuY29tcHJlc3NlZDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIERlY29tcHJlc3Npb24gbWV0aG9kIGZvciBkZWNvbXByZXNzaW5nIHRoZSBjb21wcmVzc2VkIGRhdGFcbiAgICogcmVhZCBieSByZWFkX3BhY2tldFxuICAgKi9cbiAgdGhpcy5kZWNvbXByZXNzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlY29tcHJlc3NlZDtcblxuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcbiAgICAgIGNhc2UgJ3VuY29tcHJlc3NlZCc6XG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3ppcCc6XG4gICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZDtcblxuICAgICAgICB2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZywgXCJcIik7XG4gICAgICAgIC8vIG5vIGhlYWRlciBpbiB0aGlzIGNhc2UsIGRpcmVjdGx5IGNhbGwgZGVmbGF0ZVxuICAgICAgICB2YXIganhnX29iaiA9IG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShyYWRpeCkpO1xuXG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHVuZXNjYXBlKGp4Z19vYmouZGVmbGF0ZSgpWzBdWzBdKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3psaWInOlxuICAgICAgICAvL1JGQyAxOTUwLiBCaXRzIDAtMyBDb21wcmVzc2lvbiBNZXRob2RcbiAgICAgICAgdmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkLmNoYXJDb2RlQXQoMCkgJSAweDEwO1xuXG4gICAgICAgIC8vQml0cyA0LTcgUkZDIDE5NTAgYXJlIExaNzcgV2luZG93LiBHZW5lcmFsbHkgdGhpcyB2YWx1ZSBpcyA3ID09IDMyayB3aW5kb3cgc2l6ZS5cbiAgICAgICAgLy8gMm5kIEJ5dGUgaW4gUkZDIDE5NTAgaXMgZm9yIFwiRkxBR3NcIiBBbGxvd3MgZm9yIGEgRGljdGlvbmFyeSBcbiAgICAgICAgLy8gKGhvdyBpcyB0aGlzIGRlZmluZWQpLiBCYXNpYyBjaGVja3N1bSwgYW5kIGNvbXByZXNzaW9uIGxldmVsLlxuXG4gICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSA4KSB7IC8vQ00gOCBpcyBmb3IgREVGTEFURSwgUkZDIDE5NTFcbiAgICAgICAgICAvLyByZW1vdmUgNCBieXRlcyBBRExFUjMyIGNoZWNrc3VtIGZyb20gdGhlIGVuZFxuICAgICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZC5zdWJzdHJpbmcoMCwgdGhpcy5jb21wcmVzc2VkLmxlbmd0aCAtIDQpO1xuICAgICAgICAgIHZhciByYWRpeCA9IGJhc2U2NC5lbmNvZGUoY29tcERhdGEpLnJlcGxhY2UoL1xcbi9nLCBcIlwiKTtcbiAgICAgICAgICAvL1RPRE8gY2hlY2sgQURMRVIzMiBjaGVja3N1bVxuICAgICAgICAgIGRlY29tcHJlc3NlZCA9IEpYRy5kZWNvbXByZXNzKHJhZGl4KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaTElCIG9ubHkgc3VwcG9ydHMgXCIgK1xuICAgICAgICAgICAgXCJERUZMQVRFIGNvbXByZXNzaW9uIG1ldGhvZC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2J6aXAyJzpcbiAgICAgICAgLy8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbXByZXNzaW9uIGFsZ29yaXRobSBCWmlwMiBbQloyXSBpcyBub3QgaW1wbGVtZW50ZWQuJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gdW5rbm93biA6XCIgKyB0aGlzLmFsb2dyaXRobSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMucGFja2V0cy5yZWFkKGRlY29tcHJlc3NlZCk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHJlc3MgdGhlIHBhY2tldCBkYXRhIChtZW1iZXIgZGVjb21wcmVzc2VkRGF0YSlcbiAgICovXG4gIHRoaXMuY29tcHJlc3MgPSBmdW5jdGlvbigpIHtcbiAgICBzd2l0Y2ggKHRoaXMuYWxnb3JpdGhtKSB7XG5cbiAgICAgIGNhc2UgJ3VuY29tcHJlc3NlZCc6XG4gICAgICAgIC8vIC0gVW5jb21wcmVzc2VkXG4gICAgICAgIHRoaXMuY29tcHJlc3NlZCA9IHRoaXMucGFja2V0cy53cml0ZSgpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnemlwJzpcbiAgICAgICAgLy8gLSBaSVAgW1JGQzE5NTFdXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaSVAgW1JGQzE5NTFdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgLy8gLSBaTElCIFtSRkMxOTUwXVxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaTElCIFtSRkMxOTUwXSBpcyBub3QgaW1wbGVtZW50ZWQuXCIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYnppcDInOlxuICAgICAgICAvLyAgLSBCWmlwMiBbQloyXVxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBCWmlwMiBbQloyXSBpcyBub3QgaW1wbGVtZW50ZWQuXCIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxpc3Q6IHJlcXVpcmUoJy4vcGFja2V0bGlzdC5qcycpXG59O1xuXG52YXIgcGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKTtcblxuZm9yICh2YXIgaSBpbiBwYWNrZXRzKVxuICBtb2R1bGUuZXhwb3J0c1tpXSA9IHBhY2tldHNbaV07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBMaXRlcmFsIERhdGEgUGFja2V0IChUYWcgMTEpPGJyLz5cbiAqIDxici8+XG4gKiBSRkM0ODgwIDUuOTogQSBMaXRlcmFsIERhdGEgcGFja2V0IGNvbnRhaW5zIHRoZSBib2R5IG9mIGEgbWVzc2FnZTsgZGF0YSB0aGF0XG4gKiBpcyBub3QgdG8gYmUgZnVydGhlciBpbnRlcnByZXRlZC5cbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgcGFja2V0L2xpdGVyYWxcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5mb3JtYXQgPSAndXRmOCc7IC8vIGRlZmF1bHQgZm9ybWF0IGZvciBsaXRlcmFsIGRhdGEgcGFja2V0c1xuICB0aGlzLmRhdGEgPSAnJzsgLy8gbGl0ZXJhbCBkYXRhIHJlcHJlc2VudGF0aW9uIGFzIG5hdGl2ZSBKYXZhU2NyaXB0IHN0cmluZyBvciBieXRlc1xuICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSgpO1xuXG5cbiAgLyoqXG4gICAqIFNldCB0aGUgcGFja2V0IGRhdGEgdG8gYSBqYXZhc2NyaXB0IG5hdGl2ZSBzdHJpbmcsIGVuZCBvZiBsaW5lIFxuICAgKiB3aWxsIGJlIG5vcm1hbGl6ZWQgdG8gXFxyXFxuIGFuZCBieSBkZWZhdWx0IHRleHQgaXMgY29udmVydGVkIHRvIFVURjhcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgQW55IG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKi9cbiAgdGhpcy5zZXRUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuICAgIC8vIG5vcm1hbGl6ZSBFT0wgdG8gXFxyXFxuXG4gICAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKS5yZXBsYWNlKC9cXG4vZywgJ1xcclxcbicpO1xuICAgIC8vIGVuY29kZSBVVEY4XG4gICAgdGhpcy5kYXRhID0gdGhpcy5mb3JtYXQgPT0gJ3V0ZjgnID8gdXRpbC5lbmNvZGVfdXRmOCh0ZXh0KSA6IHRleHQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBsaXRlcmFsIGRhdGEgcGFja2V0cyBhcyBuYXRpdmUgSmF2YVNjcmlwdCBzdHJpbmdcbiAgICogd2l0aCBub3JtYWxpemVkIGVuZCBvZiBsaW5lIHRvIFxcblxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGxpdGVyYWwgZGF0YSBhcyB0ZXh0XG4gICAqL1xuICB0aGlzLmdldFRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBkZWNvZGUgVVRGOFxuICAgIHZhciB0ZXh0ID0gdXRpbC5kZWNvZGVfdXRmOCh0aGlzLmRhdGEpO1xuICAgIC8vIG5vcm1hbGl6ZSBFT0wgdG8gXFxuXG4gICAgcmV0dXJuIHRleHQucmVwbGFjZSgvXFxyXFxuL2csICdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmcgb2YgYnl0ZXMuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBUaGUgc3RyaW5nIG9mIGJ5dGVzXG4gICAqIEBwYXJhbSB7dXRmOHxiaW5hcnl8dGV4dH0gZm9ybWF0IFRoZSBmb3JtYXQgb2YgdGhlIHN0cmluZyBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5zZXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzLCBmb3JtYXQpIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICB0aGlzLmRhdGEgPSBieXRlcztcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYnl0ZSBzZXF1ZW5jZSByZXByZXNlbnRpbmcgdGhlIGxpdGVyYWwgcGFja2V0IGRhdGFcbiAgICogQHJldHVybnMge1N0cmluZ30gQSBzZXF1ZW5jZSBvZiBieXRlc1xuICAgKi9cbiAgdGhpcy5nZXRCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGE7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L2xpdGVyYWx9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyAtIEEgb25lLW9jdGV0IGZpZWxkIHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgZGF0YSBpcyBmb3JtYXR0ZWQuXG5cbiAgICB2YXIgZm9ybWF0ID0gZW51bXMucmVhZChlbnVtcy5saXRlcmFsLCBieXRlcy5jaGFyQ29kZUF0KDApKTtcblxuICAgIHZhciBmaWxlbmFtZV9sZW4gPSBieXRlcy5jaGFyQ29kZUF0KDEpO1xuICAgIHRoaXMuZmlsZW5hbWUgPSB1dGlsLmRlY29kZV91dGY4KGJ5dGVzLnN1YnN0cigyLCBmaWxlbmFtZV9sZW4pKTtcblxuICAgIHRoaXMuZGF0ZSA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKDIgKyBmaWxlbmFtZV9sZW4sIDQpKTtcblxuICAgIHZhciBkYXRhID0gYnl0ZXMuc3Vic3RyaW5nKDYgKyBmaWxlbmFtZV9sZW4pO1xuXG4gICAgdGhpcy5zZXRCeXRlcyhkYXRhLCBmb3JtYXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgVGhlIGRhdGEgdG8gYmUgaW5zZXJ0ZWQgYXMgYm9keVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZy1yZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0XG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZpbGVuYW1lID0gdXRpbC5lbmNvZGVfdXRmOChcIm1zZy50eHRcIik7XG5cbiAgICB2YXIgZGF0YSA9IHRoaXMuZ2V0Qnl0ZXMoKTtcblxuICAgIHZhciByZXN1bHQgPSAnJztcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5saXRlcmFsLCB0aGlzLmZvcm1hdCkpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGZpbGVuYW1lLmxlbmd0aCk7XG4gICAgcmVzdWx0ICs9IGZpbGVuYW1lO1xuICAgIHJlc3VsdCArPSB1dGlsLndyaXRlRGF0ZSh0aGlzLmRhdGUpO1xuICAgIHJlc3VsdCArPSBkYXRhO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3RyYW5nZSBcIk1hcmtlciBwYWNrZXRcIiAoVGFnIDEwKTxici8+XG4gKiA8YnIvPlxuICogUkZDNDg4MCA1Ljg6IEFuIGV4cGVyaW1lbnRhbCB2ZXJzaW9uIG9mIFBHUCB1c2VkIHRoaXMgcGFja2V0IGFzIHRoZSBMaXRlcmFsXG4gKiBwYWNrZXQsIGJ1dCBubyByZWxlYXNlZCB2ZXJzaW9uIG9mIFBHUCBnZW5lcmF0ZWQgTGl0ZXJhbCBwYWNrZXRzIHdpdGggdGhpc1xuICogdGFnLiBXaXRoIFBHUCA1LngsIHRoaXMgcGFja2V0IGhhcyBiZWVuIHJlYXNzaWduZWQgYW5kIGlzIHJlc2VydmVkIGZvciB1c2UgYXNcbiAqIHRoZSBNYXJrZXIgcGFja2V0Ljxici8+XG4gKiA8YnIvPlxuICogU3VjaCBhIHBhY2tldCBNVVNUIGJlIGlnbm9yZWQgd2hlbiByZWNlaXZlZC5cbiAqIEBtb2R1bGUgcGFja2V0L21hcmtlclxuICovXG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBsaXRlcmFsIGRhdGEgcGFja2V0ICh0YWcgMTApLlxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgYSB0YWcgMTAgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb25cbiAgICogICAgICAgICAgICBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlblxuICAgKiAgICAgICAgICAgIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mXG4gICAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb25cbiAgICogQHJldHVybiB7bW9kdWxlOnBhY2tldC9tYXJrZXJ9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICBpZiAoYnl0ZXMuY2hhckNvZGVBdCgwKSA9PSAweDUwICYmIC8vIFBcbiAgICBieXRlcy5jaGFyQ29kZUF0KDEpID09IDB4NDcgJiYgLy8gR1xuICAgIGJ5dGVzLmNoYXJDb2RlQXQoMikgPT0gMHg1MCkgLy8gUFxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gbWFya2VyIHBhY2tldCBkb2VzIG5vdCBjb250YWluIFwiUEdQXCJcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBQYWNrZXRzIChUYWcgNCk8YnIvPlxuICogPGJyLz5cbiAqIFJGQzQ4ODAgNS40OlxuICogVGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgcHJlY2VkZXMgdGhlIHNpZ25lZCBkYXRhIGFuZCBjb250YWluc1xuICogZW5vdWdoIGluZm9ybWF0aW9uIHRvIGFsbG93IHRoZSByZWNlaXZlciB0byBiZWdpbiBjYWxjdWxhdGluZyBhbnlcbiAqIGhhc2hlcyBuZWVkZWQgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmUuICBJdCBhbGxvd3MgdGhlIFNpZ25hdHVyZVxuICogcGFja2V0IHRvIGJlIHBsYWNlZCBhdCB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlLCBzbyB0aGF0IHRoZSBzaWduZXJcbiAqIGNhbiBjb21wdXRlIHRoZSBlbnRpcmUgc2lnbmVkIG1lc3NhZ2UgaW4gb25lIHBhc3MuXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyB0eXBlL2tleWlkXG4gKiBAbW9kdWxlIHBhY2tldC9vbmVfcGFzc19zaWduYXR1cmVcbiovXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnZlcnNpb24gPSBudWxsOyAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy5cbiAgdGhpcy50eXBlID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjEuXG4gIHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS40KVxuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7IC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSB1c2VkLiAoU2VlIFJGQzQ4ODAgOS4xKVxuICB0aGlzLnNpZ25pbmdLZXlJZCA9IG51bGw7IC8vIEFuIGVpZ2h0LW9jdGV0IG51bWJlciBob2xkaW5nIHRoZSBLZXkgSUQgb2YgdGhlIHNpZ25pbmcga2V5LlxuICB0aGlzLmZsYWdzID0gbnVsbDsgLy8gIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS5cblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0ICh0YWcgNCkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDQgcGFja2V0XG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvb25lX3Bhc3Nfc2lnbmF0dXJlfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIG15cG9zID0gMDtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy5cbiAgICB0aGlzLnZlcnNpb24gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpblxuICAgIC8vICAgU2VjdGlvbiA1LjIuMS5cbiAgICB0aGlzLnR5cGUgPSBlbnVtcy5yZWFkKGVudW1zLnNpZ25hdHVyZSwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZC5cbiAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykpO1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIHVzZWQuXG4gICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBbiBlaWdodC1vY3RldCBudW1iZXIgaG9sZGluZyB0aGUgS2V5IElEIG9mIHRoZSBzaWduaW5nIGtleS5cbiAgICB0aGlzLnNpZ25pbmdLZXlJZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gICAgdGhpcy5zaWduaW5nS2V5SWQucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICBteXBvcyArPSA4O1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgYSBmbGFnIHNob3dpbmcgd2hldGhlciB0aGUgc2lnbmF0dXJlXG4gICAgLy8gICBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzXG4gICAgLy8gICBhbm90aGVyIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgdGhhdCBkZXNjcmliZXMgYW5vdGhlclxuICAgIC8vICAgc2lnbmF0dXJlIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHNhbWUgbWVzc2FnZSBkYXRhLlxuICAgIHRoaXMuZmxhZ3MgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0XG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG5cbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgzKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMudHlwZSkpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSkpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pKTtcbiAgICByZXN1bHQgKz0gdGhpcy5zaWduaW5nS2V5SWQud3JpdGUoKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmZsYWdzKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgcGFja2V0L3BhY2tldFxuICovXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlYWRTaW1wbGVMZW5ndGg6IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGxlbiA9IDAsXG4gICAgICBvZmZzZXQsXG4gICAgICB0eXBlID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuXG4gICAgaWYgKHR5cGUgPCAxOTIpIHtcbiAgICAgIGxlbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG4gICAgICBvZmZzZXQgPSAxO1xuICAgIH0gZWxzZSBpZiAodHlwZSA8IDI1NSkge1xuICAgICAgbGVuID0gKChieXRlcy5jaGFyQ29kZUF0KDApIC0gMTkyKSA8PCA4KSArIChieXRlcy5jaGFyQ29kZUF0KDEpKSArIDE5MjtcbiAgICAgIG9mZnNldCA9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlID09IDI1NSkge1xuICAgICAgbGVuID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cigxLCA0KSk7XG4gICAgICBvZmZzZXQgPSA1O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsZW46IGxlbixcbiAgICAgIG9mZnNldDogb2Zmc2V0XG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogRW5jb2RlcyBhIGdpdmVuIGludGVnZXIgb2YgbGVuZ3RoIHRvIHRoZSBvcGVucGdwIGxlbmd0aCBzcGVjaWZpZXIgdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIFRoZSBsZW5ndGggdG8gZW5jb2RlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHdpdGggb3BlbnBncCBsZW5ndGggcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHdyaXRlU2ltcGxlTGVuZ3RoOiBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICBpZiAobGVuZ3RoIDwgMTkyKSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoID4gMTkxICYmIGxlbmd0aCA8IDgzODQpIHtcbiAgICAgIC8qXG4gICAgICAgKiBsZXQgYSA9ICh0b3RhbCBkYXRhIHBhY2tldCBsZW5ndGgpIC0gMTkyIGxldCBiYyA9IHR3byBvY3RldFxuICAgICAgICogcmVwcmVzZW50YXRpb24gb2YgYSBsZXQgZCA9IGIgKyAxOTJcbiAgICAgICAqL1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChsZW5ndGggLSAxOTIpID4+IDgpICsgMTkyKTtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChsZW5ndGggLSAxOTIpICYgMHhGRik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NSk7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIHZlcnNpb24gNCB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGFcbiAgICogc3RyaW5nXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBvZiB0aGUgaGVhZGVyXG4gICAqL1xuICB3cml0ZUhlYWRlcjogZnVuY3Rpb24odGFnX3R5cGUsIGxlbmd0aCkge1xuICAgIC8qIHdlJ3JlIG9ubHkgZ2VuZXJhdGluZyB2NCBwYWNrZXQgaGVhZGVycyBoZXJlICovXG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhDMCB8IHRhZ190eXBlKTtcbiAgICByZXN1bHQgKz0gdGhpcy53cml0ZVNpbXBsZUxlbmd0aChsZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHBhY2tldCBoZWFkZXIgVmVyc2lvbiAzIHdpdGggdGhlIGdpdmVuIHRhZ190eXBlIGFuZCBsZW5ndGggdG8gYVxuICAgKiBzdHJpbmdcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdGFnX3R5cGUgVGFnIHR5cGVcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIG9mIHRoZSBwYXlsb2FkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIG9mIHRoZSBoZWFkZXJcbiAgICovXG4gIHdyaXRlT2xkSGVhZGVyOiBmdW5jdGlvbih0YWdfdHlwZSwgbGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGxlbmd0aCA8IDI1Nikge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg4MCB8ICh0YWdfdHlwZSA8PCAyKSk7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDwgNjU1MzYpIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAxKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikgfCAyKTtcbiAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKGxlbmd0aCwgNCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgc3RhdGljIFBhY2tldCBQYXJzZXIgZnVuY3Rpb25cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJlYW0gYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcGFyc2luZ1xuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIGlucHV0IGZyb20gcG9zaXRpb24gb25cbiAgICogQHJldHVybiB7T2JqZWN0fSBSZXR1cm5zIGEgcGFyc2VkIG1vZHVsZTpwYWNrZXQvcGFja2V0XG4gICAqL1xuICByZWFkOiBmdW5jdGlvbihpbnB1dCwgcG9zaXRpb24sIGxlbikge1xuICAgIC8vIHNvbWUgc2FuaXR5IGNoZWNrc1xuICAgIGlmIChpbnB1dCA9PSBudWxsIHx8IGlucHV0Lmxlbmd0aCA8PSBwb3NpdGlvbiB8fCBpbnB1dC5zdWJzdHJpbmcocG9zaXRpb24pLmxlbmd0aCA8IDIgfHwgKGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pICZcbiAgICAgIDB4ODApID09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkVycm9yIGR1cmluZyBwYXJzaW5nLiBUaGlzIG1lc3NhZ2UgLyBrZXkgaXMgcHJvYmFibHkgbm90IGNvbnRhaW5pbmcgYSB2YWxpZCBPcGVuUEdQIGZvcm1hdC5cIik7XG4gICAgfVxuICAgIHZhciBteXBvcyA9IHBvc2l0aW9uO1xuICAgIHZhciB0YWcgPSAtMTtcbiAgICB2YXIgZm9ybWF0ID0gLTE7XG4gICAgdmFyIHBhY2tldF9sZW5ndGg7XG5cbiAgICBmb3JtYXQgPSAwOyAvLyAwID0gb2xkIGZvcm1hdDsgMSA9IG5ldyBmb3JtYXRcbiAgICBpZiAoKGlucHV0LmNoYXJDb2RlQXQobXlwb3MpICYgMHg0MCkgIT0gMCkge1xuICAgICAgZm9ybWF0ID0gMTtcbiAgICB9XG5cbiAgICB2YXIgcGFja2V0X2xlbmd0aF90eXBlO1xuICAgIGlmIChmb3JtYXQpIHtcbiAgICAgIC8vIG5ldyBmb3JtYXQgaGVhZGVyXG4gICAgICB0YWcgPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4M0Y7IC8vIGJpdCA1LTBcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb2xkIGZvcm1hdCBoZWFkZXJcbiAgICAgIHRhZyA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSAmIDB4M0YpID4+IDI7IC8vIGJpdCA1LTJcbiAgICAgIHBhY2tldF9sZW5ndGhfdHlwZSA9IGlucHV0LmNoYXJDb2RlQXQobXlwb3MpICYgMHgwMzsgLy8gYml0IDEtMFxuICAgIH1cblxuICAgIC8vIGhlYWRlciBvY3RldCBwYXJzaW5nIGRvbmVcbiAgICBteXBvcysrO1xuXG4gICAgLy8gcGFyc2VkIGxlbmd0aCBmcm9tIGxlbmd0aCBmaWVsZFxuICAgIHZhciBib2R5ZGF0YSA9IG51bGw7XG5cbiAgICAvLyB1c2VkIGZvciBwYXJ0aWFsIGJvZHkgbGVuZ3Roc1xuICAgIHZhciByZWFsX3BhY2tldF9sZW5ndGggPSAtMTtcbiAgICBpZiAoIWZvcm1hdCkge1xuICAgICAgLy8gNC4yLjEuIE9sZCBGb3JtYXQgUGFja2V0IExlbmd0aHNcbiAgICAgIHN3aXRjaCAocGFja2V0X2xlbmd0aF90eXBlKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAvLyBUaGUgcGFja2V0IGhhcyBhIG9uZS1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMiBvY3RldHNcbiAgICAgICAgICAvLyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgLy8gVGhlIHBhY2tldCBoYXMgYSB0d28tb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDMgb2N0ZXRzXG4gICAgICAgICAgLy8gbG9uZy5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgPDwgOCkgfCBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgLy8gVGhlIHBhY2tldCBoYXMgYSBmb3VyLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyA1XG4gICAgICAgICAgLy8gb2N0ZXRzIGxvbmcuXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDI0KSB8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8IDE2KSB8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKyspIDw8XG4gICAgICAgICAgICA4KSB8IGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLy8gMyAtIFRoZSBwYWNrZXQgaXMgb2YgaW5kZXRlcm1pbmF0ZSBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMVxuICAgICAgICAgIC8vIG9jdGV0IGxvbmcsIGFuZCB0aGUgaW1wbGVtZW50YXRpb24gbXVzdCBkZXRlcm1pbmUgaG93IGxvbmdcbiAgICAgICAgICAvLyB0aGUgcGFja2V0IGlzLiBJZiB0aGUgcGFja2V0IGlzIGluIGEgZmlsZSwgdGhpcyBtZWFucyB0aGF0XG4gICAgICAgICAgLy8gdGhlIHBhY2tldCBleHRlbmRzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGZpbGUuIEluIGdlbmVyYWwsIFxuICAgICAgICAgIC8vIGFuIGltcGxlbWVudGF0aW9uIFNIT1VMRCBOT1QgdXNlIGluZGV0ZXJtaW5hdGUtbGVuZ3RoIFxuICAgICAgICAgIC8vIHBhY2tldHMgZXhjZXB0IHdoZXJlIHRoZSBlbmQgb2YgdGhlIGRhdGEgd2lsbCBiZSBjbGVhciBcbiAgICAgICAgICAvLyBmcm9tIHRoZSBjb250ZXh0LCBhbmQgZXZlbiB0aGVuIGl0IGlzIGJldHRlciB0byB1c2UgYSBcbiAgICAgICAgICAvLyBkZWZpbml0ZSBsZW5ndGgsIG9yIGEgbmV3IGZvcm1hdCBoZWFkZXIuIFRoZSBuZXcgZm9ybWF0IFxuICAgICAgICAgIC8vIGhlYWRlcnMgZGVzY3JpYmVkIGJlbG93IGhhdmUgYSBtZWNoYW5pc20gZm9yIHByZWNpc2VseVxuICAgICAgICAgIC8vIGVuY29kaW5nIGRhdGEgb2YgaW5kZXRlcm1pbmF0ZSBsZW5ndGguXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IGxlbjtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSAvLyA0LjIuMi4gTmV3IEZvcm1hdCBQYWNrZXQgTGVuZ3Roc1xuICAgIHtcblxuICAgICAgLy8gNC4yLjIuMS4gT25lLU9jdGV0IExlbmd0aHNcbiAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA8IDE5Mikge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjEgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gNC4yLjIuMi4gVHdvLU9jdGV0IExlbmd0aHNcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvcykgPj0gMTkyICYmIGlucHV0LmNoYXJDb2RlQXQobXlwb3MpIDwgMjI0KSB7XG4gICAgICAgIHBhY2tldF9sZW5ndGggPSAoKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykgLSAxOTIpIDw8IDgpICsgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MrKykpICsgMTkyO1xuICAgICAgICB1dGlsLnByaW50X2RlYnVnKFwiMiBieXRlIGxlbmd0aDpcIiArIHBhY2tldF9sZW5ndGgpO1xuICAgICAgICAvLyA0LjIuMi40LiBQYXJ0aWFsIEJvZHkgTGVuZ3Roc1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA+IDIyMyAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zKSA8IDI1NSkge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gMSA8PCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSAmIDB4MUYpO1xuICAgICAgICB1dGlsLnByaW50X2RlYnVnKFwiNCBieXRlIGxlbmd0aDpcIiArIHBhY2tldF9sZW5ndGgpO1xuICAgICAgICAvLyBFRUVLLCB3ZSdyZSByZWFkaW5nIHRoZSBmdWxsIGRhdGEgaGVyZS4uLlxuICAgICAgICB2YXIgbXlwb3MyID0gbXlwb3MgKyBwYWNrZXRfbGVuZ3RoO1xuICAgICAgICBib2R5ZGF0YSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChteXBvczIpIDwgMTkyKSB7XG4gICAgICAgICAgICB2YXIgdG1wbGVuID0gaW5wdXQuY2hhckNvZGVBdChteXBvczIrKyk7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPj0gMTkyICYmIGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA8IDIyNCkge1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9ICgoaW5wdXQuY2hhckNvZGVBdChteXBvczIrKykgLSAxOTIpIDw8IDgpICsgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspKSArIDE5MjtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIG15cG9zMiArPSB0bXBsZW47XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGVsc2UgaWYgKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKSA+IDIyMyAmJiBpbnB1dC5jaGFyQ29kZUF0KG15cG9zMikgPCAyNTUpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAxIDw8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSAmIDB4MUYpO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbXlwb3MyKys7XG4gICAgICAgICAgICB2YXIgdG1wbGVuID0gKGlucHV0LmNoYXJDb2RlQXQobXlwb3MyKyspIDw8IDI0KSB8IChpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKSA8PCAxNikgfCAoaW5wdXRbbXlwb3MyKytdXG4gICAgICAgICAgICAgIC5jaGFyQ29kZUF0KCkgPDwgOCkgfCBpbnB1dC5jaGFyQ29kZUF0KG15cG9zMisrKTtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIG15cG9zMiArPSB0bXBsZW47XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVhbF9wYWNrZXRfbGVuZ3RoID0gbXlwb3MyO1xuICAgICAgICAvLyA0LjIuMi4zLiBGaXZlLU9jdGV0IExlbmd0aHNcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG15cG9zKys7XG4gICAgICAgIHBhY2tldF9sZW5ndGggPSAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAyNCkgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PCAxNikgfCAoaW5wdXQuY2hhckNvZGVBdChteXBvcysrKSA8PFxuICAgICAgICAgIDgpIHwgaW5wdXQuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiB0aGVyZSB3YXMnbnQgYSBwYXJ0aWFsIGJvZHkgbGVuZ3RoOiB1c2UgdGhlIHNwZWNpZmllZFxuICAgIC8vIHBhY2tldF9sZW5ndGhcbiAgICBpZiAocmVhbF9wYWNrZXRfbGVuZ3RoID09IC0xKSB7XG4gICAgICByZWFsX3BhY2tldF9sZW5ndGggPSBwYWNrZXRfbGVuZ3RoO1xuICAgIH1cblxuICAgIGlmIChib2R5ZGF0YSA9PSBudWxsKSB7XG4gICAgICBib2R5ZGF0YSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKyByZWFsX3BhY2tldF9sZW5ndGgpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0YWc6IHRhZyxcbiAgICAgIHBhY2tldDogYm9keWRhdGEsXG4gICAgICBvZmZzZXQ6IG15cG9zICsgcmVhbF9wYWNrZXRfbGVuZ3RoXG4gICAgfTtcbiAgfVxufVxuIiwiLyoqXG4gKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsaXN0IG9mIG9wZW5wZ3AgcGFja2V0cy5cbiAqIFRha2UgY2FyZSB3aGVuIGl0ZXJhdGluZyBvdmVyIGl0IC0gdGhlIHBhY2tldHMgdGhlbXNlbHZlc1xuICogYXJlIHN0b3JlZCBhcyBudW1lcmljYWwgaW5kaWNlcy5cbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIHBhY2tldFxuICogQHJlcXVpcmVzIHBhY2tldC9wYWNrZXRcbiAqIEBtb2R1bGUgcGFja2V0L3BhY2tldGxpc3RcbiAqL1xuXG52YXIgcGFja2V0UGFyc2VyID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcbiAgcGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IHBhY2tldGxpc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKiBUaGUgbnVtYmVyIG9mIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbiB0aGUgbGlzdC5cbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtJbnRlZ2VyfSAqL1xuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLyoqXG4gICAqIFJlYWRzIGEgc3RyZWFtIG9mIGJpbmFyeSBkYXRhIGFuZCBpbnRlcnByZW50cyBpdCBhcyBhIGxpc3Qgb2YgcGFja2V0cy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IEEgYmluYXJ5IHN0cmluZyBvZiBieXRlcy5cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHZhciBwYXJzZWQgPSBwYWNrZXRQYXJzZXIucmVhZChieXRlcywgaSwgYnl0ZXMubGVuZ3RoIC0gaSk7XG4gICAgICBpID0gcGFyc2VkLm9mZnNldDtcblxuICAgICAgdmFyIHRhZyA9IGVudW1zLnJlYWQoZW51bXMucGFja2V0LCBwYXJzZWQudGFnKTtcbiAgICAgIHZhciBwYWNrZXQgPSBuZXcgcGFja2V0c1t0YWddKCk7XG5cbiAgICAgIHRoaXMucHVzaChwYWNrZXQpO1xuXG4gICAgICBwYWNrZXQucmVhZChwYXJzZWQucGFja2V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGJpbmFyeSByZXByZXNlbnRhdGlvbiBvZiBvcGVucGdwIG9iamVjdHMgY29udGFpbmVkIHdpdGhpbiB0aGVcbiAgICogY2xhc3MgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9IEEgYmluYXJ5IHN0cmluZyBvZiBieXRlcyBjb250YWluaW5nIHZhbGlkIG9wZW5wZ3AgcGFja2V0cy5cbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHBhY2tldGJ5dGVzID0gdGhpc1tpXS53cml0ZSgpO1xuICAgICAgYnl0ZXMgKz0gcGFja2V0UGFyc2VyLndyaXRlSGVhZGVyKHRoaXNbaV0udGFnLCBwYWNrZXRieXRlcy5sZW5ndGgpO1xuICAgICAgYnl0ZXMgKz0gcGFja2V0Ynl0ZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBwYWNrZXQgdG8gdGhlIGxpc3QuIFRoaXMgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIG1ldGhvZCBvZiBkb2luZyBzbztcbiAgICogd3JpdGluZyB0byBwYWNrZXRsaXN0W2ldIGRpcmVjdGx5IHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLlxuICAgKi9cbiAgdGhpcy5wdXNoID0gZnVuY3Rpb24ocGFja2V0KSB7XG4gICAgaWYgKCFwYWNrZXQpIHJldHVybjtcblxuICAgIHBhY2tldC5wYWNrZXRzID0gcGFja2V0LnBhY2tldHMgfHwgbmV3IHBhY2tldGxpc3QoKTtcblxuICAgIHRoaXNbdGhpcy5sZW5ndGhdID0gcGFja2V0O1xuICAgIHRoaXMubGVuZ3RoKys7XG4gIH1cblxuICAvKipcbiAgKiBDcmVhdGVzIGEgbmV3IHBhY2tldExpc3Qgd2l0aCBhbGwgcGFja2V0cyB0aGF0IHBhc3MgdGhlIHRlc3QgaW1wbGVtZW50ZWQgYnkgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uLlxuICAqL1xuICB0aGlzLmZpbHRlciA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cbiAgICB2YXIgZmlsdGVyZWQgPSBuZXcgcGFja2V0bGlzdCgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoY2FsbGJhY2sodGhpc1tpXSwgaSwgdGhpcykpIHtcbiAgICAgICAgZmlsdGVyZWQucHVzaCh0aGlzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmlsdGVyZWQ7XG4gIH1cblxuICAvKipcbiAgKiBDcmVhdGVzIGEgbmV3IHBhY2tldExpc3Qgd2l0aCBhbGwgcGFja2V0cyBmcm9tIHRoZSBnaXZlbiB0eXBlc1xuICAqL1xuICB0aGlzLmZpbHRlckJ5VGFnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHZhciBmaWx0ZXJlZCA9IG5ldyBwYWNrZXRsaXN0KCk7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJncy5zb21lKGZ1bmN0aW9uKHBhY2tldFR5cGUpIHtyZXR1cm4gdGhhdFtpXS50YWcgPT0gcGFja2V0VHlwZX0pKSB7XG4gICAgICAgIGZpbHRlcmVkLnB1c2godGhpc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xuICB9IFxuXG4gIC8qKlxuICAqIEV4ZWN1dGVzIHRoZSBwcm92aWRlZCBjYWxsYmFjayBvbmNlIGZvciBlYWNoIGVsZW1lbnRcbiAgKi9cbiAgdGhpcy5mb3JFYWNoID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNhbGxiYWNrKHRoaXNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmF2ZXJzZXMgcGFja2V0IHRyZWUgYW5kIHJldHVybnMgZmlyc3QgbWF0Y2hpbmcgcGFja2V0XG4gICAqIEBwYXJhbSAge21vZHVsZTplbnVtcy5wYWNrZXR9IHR5cGUgVGhlIHBhY2tldCB0eXBlXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvcGFja2V0fG51bGx9ICAgICAgXG4gICAqL1xuICB0aGlzLmZpbmRQYWNrZXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gICAgdmFyIHBhY2tldGxpc3QgPSB0aGlzLmZpbHRlckJ5VGFnKHR5cGUpO1xuICAgIGlmIChwYWNrZXRsaXN0Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHBhY2tldGxpc3RbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBmb3VuZCA9IG51bGw7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHRoaXNbaV0ucGFja2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICBmb3VuZCA9IHRoaXNbaV0ucGFja2V0cy5maW5kUGFja2V0KHR5cGUpO1xuICAgICAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYXJyYXkgb2YgZm91bmQgaW5kaWNlcyBieSB0YWdcbiAgICovXG4gIHRoaXMuaW5kZXhPZlRhZyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB2YXIgdGFnSW5kZXggPSBbXTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJncy5zb21lKGZ1bmN0aW9uKHBhY2tldFR5cGUpIHtyZXR1cm4gdGhhdFtpXS50YWcgPT0gcGFja2V0VHlwZX0pKSB7XG4gICAgICAgIHRhZ0luZGV4LnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YWdJbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHNsaWNlIG9mIHBhY2tldGxpc3RcbiAgICovXG4gIHRoaXMuc2xpY2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XG4gICAgaWYgKCFlbmQpIHtcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIHZhciBwYXJ0ID0gbmV3IHBhY2tldGxpc3QoKTtcbiAgICBmb3IgKHZhciBpID0gYmVnaW47IGkgPCBlbmQ7IGkrKykge1xuICAgICAgcGFydC5wdXNoKHRoaXNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gcGFydDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25jYXRlbmF0ZXMgcGFja2V0bGlzdCBvciBhcnJheSBvZiBwYWNrZXRzXG4gICAqL1xuICB0aGlzLmNvbmNhdCA9IGZ1bmN0aW9uKHBhY2tldGxpc3QpIHtcbiAgICBpZiAocGFja2V0bGlzdCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYWNrZXRsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMucHVzaChwYWNrZXRsaXN0W2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KTxici8+XG4gKiA8YnIvPlxuICogUkZDNDQ4MCA1LjU6XG4gKiBBIGtleSBtYXRlcmlhbCBwYWNrZXQgY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIHB1YmxpYyBvclxuICogcHJpdmF0ZSBrZXkuICBUaGVyZSBhcmUgZm91ciB2YXJpYW50cyBvZiB0aGlzIHBhY2tldCB0eXBlLCBhbmQgdHdvXG4gKiBtYWpvciB2ZXJzaW9ucy4gIENvbnNlcXVlbnRseSwgdGhpcyBzZWN0aW9uIGlzIGNvbXBsZXguXG4gKiBAcmVxdWlyZXMgY3J5cHRvXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyB0eXBlL2tleWlkXG4gKiBAcmVxdWlyZXMgdHlwZS9tcGlcbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIHBhY2tldC9wdWJsaWNfa2V5XG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKSxcbiAgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudmVyc2lvbiA9IDQ7XG4gIC8qKiBLZXkgY3JlYXRpb24gZGF0ZS5cbiAgICogQHR5cGUge0RhdGV9ICovXG4gIHRoaXMuY3JlYXRlZCA9IG5ldyBEYXRlKCk7XG4gIC8qKiBBIGxpc3Qgb2YgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHR5cGUge21vZHVsZTp0eXBlL21waX0gKi9cbiAgdGhpcy5tcGkgPSBbXTtcbiAgLyoqIFB1YmxpYyBrZXkgYWxnb3JpdGhtXG4gICAqIEB0eXBlIHttb2R1bGU6ZW51bXMucHVibGljS2V5fSAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICdyc2Ffc2lnbic7XG4gIC8vIHRpbWUgaW4gZGF5cyAoVjMgb25seSlcbiAgdGhpcy5leHBpcmF0aW9uVGltZVYzID0gMDtcblxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBQYXJzZXIgZm9yIHB1YmxpYyBrZXlzIGFzIHNwZWNpZmllZCBpbiBSRkMgNDg4MCBzZWN0aW9uIFxuICAgKiA1LjUuMiBQdWJsaWMtS2V5IFBhY2tldCBGb3JtYXRzXG4gICAqIGNhbGxlZCBieSByZWFkX3RhZyZsdDtudW0mZ3Q7XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0IGZyb21cbiAgICogQHJldHVybiB7T2JqZWN0fSBUaGlzIG9iamVjdCB3aXRoIGF0dHJpYnV0ZXMgc2V0IGJ5IHRoZSBwYXJzZXJcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgLy8gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIgKDMgb3IgNCkuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdChwb3MrKyk7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09IDMgfHwgdGhpcy52ZXJzaW9uID09IDQpIHtcbiAgICAgIC8vIC0gQSBmb3VyLW9jdGV0IG51bWJlciBkZW5vdGluZyB0aGUgdGltZSB0aGF0IHRoZSBrZXkgd2FzIGNyZWF0ZWQuXG4gICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihwb3MsIDQpKTtcbiAgICAgIHBvcyArPSA0O1xuXG4gICAgICBpZiAodGhpcy52ZXJzaW9uID09IDMpIHtcbiAgICAgICAgLy8gLSBBIHR3by1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHRpbWUgaW4gZGF5cyB0aGF0IHRoaXMga2V5IGlzXG4gICAgICAgIC8vICAgdmFsaWQuICBJZiB0aGlzIG51bWJlciBpcyB6ZXJvLCB0aGVuIGl0IGRvZXMgbm90IGV4cGlyZS5cbiAgICAgICAgdGhpcy5leHBpcmF0aW9uVGltZVYzID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihwb3MsIDIpKTtcbiAgICAgICAgcG9zICs9IDI7XG4gICAgICB9XG5cbiAgICAgIC8vIC0gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSBvZiB0aGlzIGtleS5cbiAgICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzLmNoYXJDb2RlQXQocG9zKyspKTtcblxuICAgICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIHRoaXMubXBpID0gW107XG5cbiAgICAgIHZhciBibXBpID0gYnl0ZXMuc3Vic3RyKHBvcyk7XG4gICAgICB2YXIgcCA9IDA7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpY291bnQgJiYgcCA8IGJtcGkubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICB0aGlzLm1waVtpXSA9IG5ldyB0eXBlX21waSgpO1xuXG4gICAgICAgIHAgKz0gdGhpcy5tcGlbaV0ucmVhZChibXBpLnN1YnN0cihwKSlcblxuICAgICAgICBpZiAocCA+IGJtcGkubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciByZWFkaW5nIE1QSSBAOicgKyBwKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcCArIDY7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVmVyc2lvbiAnICsgdmVyc2lvbiArICcgb2YgdGhlIGtleSBwYWNrZXQgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBbGlhcyBvZiByZWFkKClcbiAgICogQGZ1bmN0aW9uIG1vZHVsZTpwYWNrZXQvcHVibGljX2tleSNyZWFkUHVibGljS2V5XG4gICAqIEBzZWUgbW9kdWxlOnBhY2tldC9wdWJsaWNfa2V5I3JlYWRcbiAgICovXG4gIHRoaXMucmVhZFB1YmxpY0tleSA9IHRoaXMucmVhZDtcblxuICAvKipcbiAgICogU2FtZSBhcyB3cml0ZV9wcml2YXRlX2tleSwgYnV0IGhhcyBsZXNzIGluZm9ybWF0aW9uIGJlY2F1c2Ugb2YgXG4gICAqIHB1YmxpYyBrZXkuXG4gICAqIEByZXR1cm4ge09iamVjdH0ge2JvZHk6IFtzdHJpbmddT3BlblBHUCBwYWNrZXQgYm9keSBjb250ZW50cyxcbiAgICogaGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9XG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gVmVyc2lvblxuICAgIHZhciByZXN1bHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudmVyc2lvbik7XG4gICAgcmVzdWx0ICs9IHV0aWwud3JpdGVEYXRlKHRoaXMuY3JlYXRlZCk7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PSAzKSB7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLmV4cGlyYXRpb25UaW1lVjMsIDIpO1xuICAgIH1cbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMuYWxnb3JpdGhtKSk7XG5cbiAgICB2YXIgbXBpY291bnQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQodGhpcy5hbGdvcml0aG0pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5tcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBBbGlhcyBvZiB3cml0ZSgpXG4gICAqIEBmdW5jdGlvbiBtb2R1bGU6cGFja2V0L3B1YmxpY19rZXkjd3JpdGVQdWJsaWNLZXlcbiAgICogQHNlZSBtb2R1bGU6cGFja2V0L3B1YmxpY19rZXkjd3JpdGVcbiAgICovXG4gIHRoaXMud3JpdGVQdWJsaWNLZXkgPSB0aGlzLndyaXRlO1xuXG4gIC8qKlxuICAgKiBXcml0ZSBhbiBvbGQgdmVyc2lvbiBwYWNrZXQgLSBpdCdzIHVzZWQgYnkgc29tZSBvZiB0aGUgaW50ZXJuYWwgcm91dGluZXMuXG4gICAqL1xuICB0aGlzLndyaXRlT2xkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkgK1xuICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDIpICtcbiAgICAgIGJ5dGVzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBrZXkgaWQgb2YgdGhlIGtleSBcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIDggYnl0ZSBrZXkgaWRcbiAgICovXG4gIHRoaXMuZ2V0S2V5SWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIga2V5aWQgPSBuZXcgdHlwZV9rZXlpZCgpO1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT0gNCkge1xuICAgICAga2V5aWQucmVhZCh0aGlzLmdldEZpbmdlcnByaW50KCkuc3Vic3RyKDEyLCA4KSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnZlcnNpb24gPT0gMykge1xuICAgICAga2V5aWQucmVhZCh0aGlzLm1waVswXS53cml0ZSgpLnN1YnN0cigtOCkpO1xuICAgIH1cbiAgICByZXR1cm4ga2V5aWQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIGZpbmdlcnByaW50IG9mIHRoZSBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSBmaW5nZXJwcmludFxuICAgKi9cbiAgdGhpcy5nZXRGaW5nZXJwcmludCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0b0hhc2ggPSAnJztcbiAgICBpZiAodGhpcy52ZXJzaW9uID09IDQpIHtcbiAgICAgIHRvSGFzaCA9IHRoaXMud3JpdGVPbGQoKTtcbiAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5zaGExKHRvSGFzaCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnZlcnNpb24gPT0gMykge1xuICAgICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpY291bnQ7IGkrKykge1xuICAgICAgICB0b0hhc2ggKz0gdGhpcy5tcGlbaV0udG9CeXRlcygpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLm1kNSh0b0hhc2gpXG4gICAgfVxuICB9O1xufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpPGJyLz5cbiAqIDxici8+XG4gKiBSRkM0ODgwIDUuMTogQSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQgaG9sZHMgdGhlIHNlc3Npb24ga2V5XG4gKiB1c2VkIHRvIGVuY3J5cHQgYSBtZXNzYWdlLiBaZXJvIG9yIG1vcmUgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXlcbiAqIHBhY2tldHMgYW5kL29yIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldHMgbWF5IHByZWNlZGUgYVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIHdoaWNoIGhvbGRzIGFuIGVuY3J5cHRlZCBtZXNzYWdlLiBUaGVcbiAqIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlIHNlc3Npb24ga2V5IGlzIGl0c2VsZlxuICogZW5jcnlwdGVkIGFuZCBzdG9yZWQgaW4gdGhlIEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQocykuIFRoZVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgaXMgcHJlY2VkZWQgYnkgb25lIFB1YmxpYy1LZXkgRW5jcnlwdGVkXG4gKiBTZXNzaW9uIEtleSBwYWNrZXQgZm9yIGVhY2ggT3BlblBHUCBrZXkgdG8gd2hpY2ggdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkLlxuICogVGhlIHJlY2lwaWVudCBvZiB0aGUgbWVzc2FnZSBmaW5kcyBhIHNlc3Npb24ga2V5IHRoYXQgaXMgZW5jcnlwdGVkIHRvIHRoZWlyXG4gKiBwdWJsaWMga2V5LCBkZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGVuIHVzZXMgdGhlIHNlc3Npb24ga2V5IHRvXG4gKiBkZWNyeXB0IHRoZSBtZXNzYWdlLlxuICogQHJlcXVpcmVzIGNyeXB0b1xuICogQHJlcXVpcmVzIGVudW1zXG4gKiBAcmVxdWlyZXMgdHlwZS9rZXlpZFxuICogQHJlcXVpcmVzIHR5cGUvbXBpXG4gKiBAcmVxdWlyZXMgdXRpbFxuICogQG1vZHVsZSBwYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXlcbiAqL1xuXG52YXIgdHlwZV9rZXlpZCA9IHJlcXVpcmUoJy4uL3R5cGUva2V5aWQuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy52ZXJzaW9uID0gMztcblxuICB0aGlzLnB1YmxpY0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcbiAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSAncnNhX2VuY3J5cHQnO1xuXG4gIHRoaXMuc2Vzc2lvbktleSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuXG4gIC8qKiBAdHlwZSB7QXJyYXk8bW9kdWxlOnR5cGUvbXBpPn0gKi9cbiAgdGhpcy5lbmNyeXB0ZWQgPSBbXTtcblxuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBwdWJsaWNrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5IHBhY2tldCAodGFnIDEpLlxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgYSB0YWcgMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXl9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG4gICAgdGhpcy5wdWJsaWNLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cigxKSk7XG4gICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgYnl0ZXMuY2hhckNvZGVBdCg5KSk7XG5cbiAgICB2YXIgaSA9IDEwO1xuXG4gICAgdmFyIGludGVnZXJDb3VudCA9IChmdW5jdGlvbihhbGdvKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgICByZXR1cm4gMTtcblxuICAgICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgICByZXR1cm4gMjtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYWxnb3JpdGhtLlwiKTtcbiAgICAgIH1cbiAgICB9KSh0aGlzLnB1YmxpY0tleUFsZ29yaXRobSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IFtdO1xuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBpbnRlZ2VyQ291bnQ7IGorKykge1xuICAgICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgaSArPSBtcGkucmVhZChieXRlcy5zdWJzdHIoaSkpO1xuICAgICAgdGhpcy5lbmNyeXB0ZWQucHVzaChtcGkpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHVibGljS2V5SWRcbiAgICogICAgICAgICAgICAgVGhlIHB1YmxpYyBrZXkgaWQgY29ycmVzcG9uZGluZyB0byBwdWJsaWNNUElzIGtleSBhcyBzdHJpbmdcbiAgICogQHBhcmFtIHtBcnJheTxtb2R1bGU6dHlwZS9tcGk+fSBwdWJsaWNNUElzXG4gICAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwdWJhbGdvXG4gICAqICAgICAgICAgICAgVGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBhbGdvcml0aG0gLy8gU2VlIFJGQzQ4ODAgOS4xXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ29cbiAgICogICAgICAgICAgICBUaGUgc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhIFxuICAgKiAgICAgICAgICAgIHdpdGhpbiBhbiBlbmNyeXB0ZWRkYXRhcGFja2V0IG9yIGVuY3J5cHRlZGludGVncml0eS1cbiAgICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IFxuICAgKiAgICAgICAgICAgIGZvbGxvd2luZyB0aGlzIHBhY2tldCAvL1NlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2Vzc2lvbmtleVxuICAgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pO1xuICAgIHJlc3VsdCArPSB0aGlzLnB1YmxpY0tleUlkLndyaXRlKCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW5jcnlwdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5lbmNyeXB0ZWRbaV0ud3JpdGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0pKTtcblxuICAgIGRhdGEgKz0gdGhpcy5zZXNzaW9uS2V5O1xuICAgIHZhciBjaGVja3N1bSA9IHV0aWwuY2FsY19jaGVja3N1bSh0aGlzLnNlc3Npb25LZXkpO1xuICAgIGRhdGEgKz0gdXRpbC53cml0ZU51bWJlcihjaGVja3N1bSwgMik7XG5cbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CeXRlcyhjcnlwdG8ucGtjczEuZW1lLmVuY29kZShcbiAgICAgIGRhdGEsXG4gICAgICBrZXkubXBpWzBdLmJ5dGVMZW5ndGgoKSkpO1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBjcnlwdG8ucHVibGljS2V5RW5jcnlwdChcbiAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAga2V5Lm1waSxcbiAgICAgIG1waSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSAob25seSBmb3IgcHVibGljIGtleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICogcGFja2V0cyAodGFnIDEpXG4gICAqIFxuICAgKiBAcGFyYW0ge21vZHVsZTpwYWNrZXQvc2VjcmV0X2tleX0ga2V5XG4gICAqICAgICAgICAgICAgUHJpdmF0ZSBrZXkgd2l0aCBzZWNNUElzIHVubG9ja2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHVuZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgcmVzdWx0ID0gY3J5cHRvLnB1YmxpY0tleURlY3J5cHQoXG4gICAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSxcbiAgICAgIGtleS5tcGksXG4gICAgICB0aGlzLmVuY3J5cHRlZCkudG9CeXRlcygpO1xuXG4gICAgdmFyIGNoZWNrc3VtID0gdXRpbC5yZWFkTnVtYmVyKHJlc3VsdC5zdWJzdHIocmVzdWx0Lmxlbmd0aCAtIDIpKTtcblxuICAgIHZhciBkZWNvZGVkID0gY3J5cHRvLnBrY3MxLmVtZS5kZWNvZGUoXG4gICAgICByZXN1bHQsXG4gICAgICBrZXkubXBpWzBdLmJ5dGVMZW5ndGgoKSk7XG5cbiAgICB2YXIga2V5ID0gZGVjb2RlZC5zdWJzdHJpbmcoMSwgZGVjb2RlZC5sZW5ndGggLSAyKTtcblxuICAgIGlmIChjaGVja3N1bSAhPSB1dGlsLmNhbGNfY2hlY2tzdW0oa2V5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVja3N1bSBtaXNtYXRjaCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlc3Npb25LZXkgPSBrZXk7XG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPVxuICAgICAgICBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgZGVjb2RlZC5jaGFyQ29kZUF0KDApKTtcbiAgICB9XG4gIH07XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAcmVxdWlyZXMgcGFja2V0L3B1YmxpY19rZXlcbiAqIEBtb2R1bGUgcGFja2V0L3B1YmxpY19zdWJrZXlcbiAqL1xuXG52YXIgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBtb2R1bGU6cGFja2V0L3B1YmxpY19rZXlcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHB1YmxpY0tleS5jYWxsKHRoaXMpO1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KTxici8+XG4gKiA8YnIvPlxuICogUkZDNDQ4MCA1LjU6XG4gKiBBIGtleSBtYXRlcmlhbCBwYWNrZXQgY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIHB1YmxpYyBvclxuICogcHJpdmF0ZSBrZXkuICBUaGVyZSBhcmUgZm91ciB2YXJpYW50cyBvZiB0aGlzIHBhY2tldCB0eXBlLCBhbmQgdHdvXG4gKiBtYWpvciB2ZXJzaW9ucy4gIENvbnNlcXVlbnRseSwgdGhpcyBzZWN0aW9uIGlzIGNvbXBsZXguXG4gKiBAcmVxdWlyZXMgY3J5cHRvXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyBwYWNrZXQvcHVibGljX2tleVxuICogQHJlcXVpcmVzIHR5cGUvbXBpXG4gKiBAcmVxdWlyZXMgdHlwZS9zMmtcbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIHBhY2tldC9zZWNyZXRfa2V5XG4gKi9cblxudmFyIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIG1vZHVsZTpwYWNrZXQvcHVibGljX2tleVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgcHVibGljS2V5LmNhbGwodGhpcyk7XG4gIC8vIGVuY3J5cHRlZCBzZWNyZXQta2V5IGRhdGFcbiAgdGhpcy5lbmNyeXB0ZWQgPSBudWxsO1xuICAvLyBpbmRpY2F0b3IgaWYgc2VjcmV0LWtleSBkYXRhIGlzIGF2YWlsYWJsZSBpbiBkZWNyeXB0ZWQgZm9ybVxuICB0aGlzLmlzRGVjcnlwdGVkID0gZmFsc2U7XG5cblxuICBmdW5jdGlvbiBnZXRfaGFzaF9sZW4oaGFzaCkge1xuICAgIGlmIChoYXNoID09ICdzaGExJylcbiAgICAgIHJldHVybiAyMDtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gMjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldF9oYXNoX2ZuKGhhc2gpIHtcbiAgICBpZiAoaGFzaCA9PSAnc2hhMScpXG4gICAgICByZXR1cm4gY3J5cHRvLmhhc2guc2hhMTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gZnVuY3Rpb24oYykge1xuICAgICAgICByZXR1cm4gdXRpbC53cml0ZU51bWJlcih1dGlsLmNhbGNfY2hlY2tzdW0oYyksIDIpO1xuICAgIH07XG4gIH1cblxuICAvLyBIZWxwZXIgZnVuY3Rpb25cblxuICBmdW5jdGlvbiBwYXJzZV9jbGVhcnRleHRfbXBpKGhhc2hfYWxnb3JpdGhtLCBjbGVhcnRleHQsIGFsZ29yaXRobSkge1xuICAgIHZhciBoYXNobGVuID0gZ2V0X2hhc2hfbGVuKGhhc2hfYWxnb3JpdGhtKSxcbiAgICAgIGhhc2hmbiA9IGdldF9oYXNoX2ZuKGhhc2hfYWxnb3JpdGhtKTtcblxuICAgIHZhciBoYXNodGV4dCA9IGNsZWFydGV4dC5zdWJzdHIoY2xlYXJ0ZXh0Lmxlbmd0aCAtIGhhc2hsZW4pO1xuICAgIGNsZWFydGV4dCA9IGNsZWFydGV4dC5zdWJzdHIoMCwgY2xlYXJ0ZXh0Lmxlbmd0aCAtIGhhc2hsZW4pO1xuXG4gICAgdmFyIGhhc2ggPSBoYXNoZm4oY2xlYXJ0ZXh0KTtcblxuICAgIGlmIChoYXNoICE9IGhhc2h0ZXh0KVxuICAgICAgcmV0dXJuIG5ldyBFcnJvcihcIkhhc2ggbWlzbWF0Y2guXCIpO1xuXG4gICAgdmFyIG1waXMgPSBjcnlwdG8uZ2V0UHJpdmF0ZU1waUNvdW50KGFsZ29yaXRobSk7XG5cbiAgICB2YXIgaiA9IDA7XG4gICAgdmFyIG1waSA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGlzICYmIGogPCBjbGVhcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgIG1waVtpXSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgaiArPSBtcGlbaV0ucmVhZChjbGVhcnRleHQuc3Vic3RyKGopKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbXBpO1xuICB9XG5cbiAgZnVuY3Rpb24gd3JpdGVfY2xlYXJ0ZXh0X21waShoYXNoX2FsZ29yaXRobSwgYWxnb3JpdGhtLCBtcGkpIHtcbiAgICB2YXIgYnl0ZXMgPSAnJztcbiAgICB2YXIgZGlzY2FyZCA9IGNyeXB0by5nZXRQdWJsaWNNcGlDb3VudChhbGdvcml0aG0pO1xuXG4gICAgZm9yICh2YXIgaSA9IGRpc2NhcmQ7IGkgPCBtcGkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGJ5dGVzICs9IG1waVtpXS53cml0ZSgpO1xuICAgIH1cblxuXG4gICAgYnl0ZXMgKz0gZ2V0X2hhc2hfZm4oaGFzaF9hbGdvcml0aG0pKGJ5dGVzKTtcblxuICAgIHJldHVybiBieXRlcztcbiAgfVxuXG5cbiAgLy8gNS41LjMuICBTZWNyZXQtS2V5IFBhY2tldCBGb3JtYXRzXG5cbiAgLyoqXG4gICAqIEludGVybmFsIHBhcnNlciBmb3IgcHJpdmF0ZSBrZXlzIGFzIHNwZWNpZmllZCBpbiBSRkMgNDg4MCBzZWN0aW9uIDUuNS4zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0IGZyb21cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIFB1YmxpYy1LZXkgb3IgUHVibGljLVN1YmtleSBwYWNrZXQsIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgICB2YXIgbGVuID0gdGhpcy5yZWFkUHVibGljS2V5KGJ5dGVzKTtcblxuICAgIGJ5dGVzID0gYnl0ZXMuc3Vic3RyKGxlbik7XG5cblxuICAgIC8vIC0gT25lIG9jdGV0IGluZGljYXRpbmcgc3RyaW5nLXRvLWtleSB1c2FnZSBjb252ZW50aW9ucy4gIFplcm9cbiAgICAvLyAgIGluZGljYXRlcyB0aGF0IHRoZSBzZWNyZXQta2V5IGRhdGEgaXMgbm90IGVuY3J5cHRlZC4gIDI1NSBvciAyNTRcbiAgICAvLyAgIGluZGljYXRlcyB0aGF0IGEgc3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgaXMgYmVpbmcgZ2l2ZW4uICBBbnlcbiAgICAvLyAgIG90aGVyIHZhbHVlIGlzIGEgc3ltbWV0cmljLWtleSBlbmNyeXB0aW9uIGFsZ29yaXRobSBpZGVudGlmaWVyLlxuICAgIHZhciBpc0VuY3J5cHRlZCA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICBpZiAoaXNFbmNyeXB0ZWQpIHtcbiAgICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXM7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gLSBQbGFpbiBvciBlbmNyeXB0ZWQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgY29tcHJpc2luZyB0aGUgc2VjcmV0XG4gICAgICAvLyAgIGtleSBkYXRhLiAgVGhlc2UgYWxnb3JpdGhtLXNwZWNpZmljIGZpZWxkcyBhcmUgYXMgZGVzY3JpYmVkXG4gICAgICAvLyAgIGJlbG93LlxuICAgICAgdmFyIHBhcnNlZE1QSSA9IHBhcnNlX2NsZWFydGV4dF9tcGkoJ21vZCcsIGJ5dGVzLnN1YnN0cigxKSwgdGhpcy5hbGdvcml0aG0pO1xuICAgICAgaWYgKHBhcnNlZE1QSSBpbnN0YW5jZW9mIEVycm9yKVxuICAgICAgICB0aHJvdyBwYXJzZWRNUEk7XG4gICAgICB0aGlzLm1waSA9IHRoaXMubXBpLmNvbmNhdChwYXJzZWRNUEkpO1xuICAgICAgdGhpcy5pc0RlY3J5cHRlZCA9IHRydWU7XG4gICAgfVxuXG4gIH07XG5cbiAgLyoqIENyZWF0ZXMgYW4gT3BlblBHUCBrZXkgcGFja2V0IGZvciB0aGUgZ2l2ZW4ga2V5LlxuICAgICogQHJldHVybiB7U3RyaW5nfSBBIHN0cmluZyBvZiBieXRlcyBjb250YWluaW5nIHRoZSBzZWNyZXQga2V5IE9wZW5QR1AgcGFja2V0XG4gICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBieXRlcyA9IHRoaXMud3JpdGVQdWJsaWNLZXkoKTtcblxuICAgIGlmICghdGhpcy5lbmNyeXB0ZWQpIHtcbiAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG5cbiAgICAgIGJ5dGVzICs9IHdyaXRlX2NsZWFydGV4dF9tcGkoJ21vZCcsIHRoaXMuYWxnb3JpdGhtLCB0aGlzLm1waSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ5dGVzICs9IHRoaXMuZW5jcnlwdGVkO1xuICAgIH1cblxuICAgIHJldHVybiBieXRlcztcbiAgfTtcblxuXG5cblxuICAvKiogRW5jcnlwdCB0aGUgcGF5bG9hZC4gQnkgZGVmYXVsdCwgd2UgdXNlIGFlczI1NiBhbmQgaXRlcmF0ZWQsIHNhbHRlZCBzdHJpbmdcbiAgICogdG8ga2V5IHNwZWNpZmllclxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFzc3BocmFzZVxuICAgKi9cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuXG4gICAgdmFyIHMyayA9IG5ldyB0eXBlX3MyaygpLFxuICAgICAgc3ltbWV0cmljID0gJ2FlczI1NicsXG4gICAgICBjbGVhcnRleHQgPSB3cml0ZV9jbGVhcnRleHRfbXBpKCdzaGExJywgdGhpcy5hbGdvcml0aG0sIHRoaXMubXBpKSxcbiAgICAgIGtleSA9IHByb2R1Y2VFbmNyeXB0aW9uS2V5KHMyaywgcGFzc3BocmFzZSwgc3ltbWV0cmljKSxcbiAgICAgIGJsb2NrTGVuID0gY3J5cHRvLmNpcGhlcltzeW1tZXRyaWNdLmJsb2NrU2l6ZSxcbiAgICAgIGl2ID0gY3J5cHRvLnJhbmRvbS5nZXRSYW5kb21CeXRlcyhibG9ja0xlbik7XG5cblxuICAgIHRoaXMuZW5jcnlwdGVkID0gJyc7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyNTQpO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpKTtcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBzMmsud3JpdGUoKTtcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBpdjtcblxuICAgIHRoaXMuZW5jcnlwdGVkICs9IGNyeXB0by5jZmIubm9ybWFsRW5jcnlwdChzeW1tZXRyaWMsIGtleSwgY2xlYXJ0ZXh0LCBpdik7XG4gIH07XG5cbiAgZnVuY3Rpb24gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBhbGdvcml0aG0pIHtcbiAgICByZXR1cm4gczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsXG4gICAgICBjcnlwdG8uY2lwaGVyW2FsZ29yaXRobV0ua2V5U2l6ZSk7XG4gIH1cblxuICAvKipcbiAgICogRGVjcnlwdHMgdGhlIHByaXZhdGUga2V5IE1QSXMgd2hpY2ggYXJlIG5lZWRlZCB0byB1c2UgdGhlIGtleS5cbiAgICogQGxpbmsgbW9kdWxlOnBhY2tldC9zZWNyZXRfa2V5LmlzRGVjcnlwdGVkIHNob3VsZCBiZVxuICAgKiBmYWxzZSBvdGhlcndpc2UgYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24gaXMgbm90IG5lZWRlZFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0cl9wYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIGZvciB0aGlzIHByaXZhdGUga2V5IFxuICAgKiBhcyBzdHJpbmdcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc3BocmFzZSB3YXMgY29ycmVjdCBvciBNUEkgYWxyZWFkeVxuICAgKiAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWQ7IGZhbHNlIGlmIG5vdFxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICAgIGlmICh0aGlzLmlzRGVjcnlwdGVkKVxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICB2YXIgaSA9IDAsXG4gICAgICBzeW1tZXRyaWMsXG4gICAgICBrZXk7XG5cbiAgICB2YXIgczJrX3VzYWdlID0gdGhpcy5lbmNyeXB0ZWQuY2hhckNvZGVBdChpKyspO1xuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXQgd2FzIDI1NSBvciAyNTQsIGEgb25lLVxuICAgIC8vICAgb2N0ZXQgc3ltbWV0cmljIGVuY3J5cHRpb24gYWxnb3JpdGhtLlxuICAgIGlmIChzMmtfdXNhZ2UgPT0gMjU1IHx8IHMya191c2FnZSA9PSAyNTQpIHtcbiAgICAgIHN5bW1ldHJpYyA9IHRoaXMuZW5jcnlwdGVkLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuXG4gICAgICAvLyAtIFtPcHRpb25hbF0gSWYgc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldCB3YXMgMjU1IG9yIDI1NCwgYVxuICAgICAgLy8gICBzdHJpbmctdG8ta2V5IHNwZWNpZmllci4gIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy10by1rZXlcbiAgICAgIC8vICAgc3BlY2lmaWVyIGlzIGltcGxpZWQgYnkgaXRzIHR5cGUsIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgICAgIHZhciBzMmsgPSBuZXcgdHlwZV9zMmsoKTtcbiAgICAgIGkgKz0gczJrLnJlYWQodGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpKTtcblxuICAgICAga2V5ID0gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBzeW1tZXRyaWMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzeW1tZXRyaWMgPSBzMmtfdXNhZ2U7XG4gICAgICBzeW1tZXRyaWMgPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKTtcbiAgICAgIGtleSA9IGNyeXB0by5oYXNoLm1kNShwYXNzcGhyYXNlKTtcbiAgICB9XG5cblxuICAgIC8vIC0gW09wdGlvbmFsXSBJZiBzZWNyZXQgZGF0YSBpcyBlbmNyeXB0ZWQgKHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXRcbiAgICAvLyAgIG5vdCB6ZXJvKSwgYW4gSW5pdGlhbCBWZWN0b3IgKElWKSBvZiB0aGUgc2FtZSBsZW5ndGggYXMgdGhlXG4gICAgLy8gICBjaXBoZXIncyBibG9jayBzaXplLlxuICAgIHZhciBpdiA9IHRoaXMuZW5jcnlwdGVkLnN1YnN0cihpLFxuICAgICAgY3J5cHRvLmNpcGhlcltzeW1tZXRyaWNdLmJsb2NrU2l6ZSk7XG5cbiAgICBpICs9IGl2Lmxlbmd0aDtcblxuICAgIHZhciBjbGVhcnRleHQsXG4gICAgICBjaXBoZXJ0ZXh0ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpO1xuXG4gICAgY2xlYXJ0ZXh0ID0gY3J5cHRvLmNmYi5ub3JtYWxEZWNyeXB0KHN5bW1ldHJpYywga2V5LCBjaXBoZXJ0ZXh0LCBpdik7XG5cbiAgICB2YXIgaGFzaCA9IHMya191c2FnZSA9PSAyNTQgP1xuICAgICAgJ3NoYTEnIDpcbiAgICAgICdtb2QnO1xuXG4gICAgdmFyIHBhcnNlZE1QSSA9IHBhcnNlX2NsZWFydGV4dF9tcGkoaGFzaCwgY2xlYXJ0ZXh0LCB0aGlzLmFsZ29yaXRobSk7XG4gICAgaWYgKHBhcnNlZE1QSSBpbnN0YW5jZW9mIEVycm9yKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHRoaXMubXBpID0gdGhpcy5tcGkuY29uY2F0KHBhcnNlZE1QSSk7XG4gICAgdGhpcy5pc0RlY3J5cHRlZCA9IHRydWU7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgdGhpcy5nZW5lcmF0ZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICB0aGlzLm1waSA9IGNyeXB0by5nZW5lcmF0ZU1waSh0aGlzLmFsZ29yaXRobSwgYml0cyk7XG4gICAgdGhpcy5pc0RlY3J5cHRlZCA9IHRydWU7XG4gIH07XG5cbn1cblxubW9kdWxlLmV4cG9ydHMucHJvdG90eXBlID0gbmV3IHB1YmxpY0tleSgpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAcmVxdWlyZXMgcGFja2V0L3NlY3JldF9rZXlcbiAqIEBtb2R1bGUgcGFja2V0L3NlY3JldF9zdWJrZXlcbiAqL1xuXG52YXIgc2VjcmV0S2V5ID0gcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBtb2R1bGU6cGFja2V0L3NlY3JldF9rZXlcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHNlY3JldEtleS5jYWxsKHRoaXMpO1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2lnbmF0dXJlIFBhY2tldCAoVGFnIDIpPGJyLz5cbiAqIDxici8+XG4gKiBSRkM0NDgwIDUuMjpcbiAqIEEgU2lnbmF0dXJlIHBhY2tldCBkZXNjcmliZXMgYSBiaW5kaW5nIGJldHdlZW4gc29tZSBwdWJsaWMga2V5IGFuZFxuICogc29tZSBkYXRhLiAgVGhlIG1vc3QgY29tbW9uIHNpZ25hdHVyZXMgYXJlIGEgc2lnbmF0dXJlIG9mIGEgZmlsZSBvciBhXG4gKiBibG9jayBvZiB0ZXh0LCBhbmQgYSBzaWduYXR1cmUgdGhhdCBpcyBhIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElELlxuICogQHJlcXVpcmVzIGNyeXB0b1xuICogQHJlcXVpcmVzIGVudW1zXG4gKiBAcmVxdWlyZXMgcGFja2V0L3BhY2tldFxuICogQHJlcXVpcmVzIHR5cGUva2V5aWRcbiAqIEByZXF1aXJlcyB0eXBlL21waVxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgcGFja2V0L3NpZ25hdHVyZVxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gcGFja2V0U2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuXG4gIHRoaXMudmVyc2lvbiA9IDQ7XG4gIHRoaXMuc2lnbmF0dXJlVHlwZSA9IG51bGw7XG4gIHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDtcblxuICB0aGlzLnNpZ25hdHVyZURhdGEgPSBudWxsO1xuICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IG51bGw7XG4gIHRoaXMubXBpID0gbnVsbDtcblxuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICB0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMgPSB0cnVlO1xuICB0aGlzLmV4cG9ydGFibGUgPSBudWxsO1xuICB0aGlzLnRydXN0TGV2ZWwgPSBudWxsO1xuICB0aGlzLnRydXN0QW1vdW50ID0gbnVsbDtcbiAgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IG51bGw7XG4gIHRoaXMucmV2b2NhYmxlID0gbnVsbDtcbiAgdGhpcy5rZXlFeHBpcmF0aW9uVGltZSA9IG51bGw7XG4gIHRoaXMua2V5TmV2ZXJFeHBpcmVzID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5Q2xhc3MgPSBudWxsO1xuICB0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBudWxsO1xuICB0aGlzLnJldm9jYXRpb25LZXlGaW5nZXJwcmludCA9IG51bGw7XG4gIHRoaXMuaXNzdWVyS2V5SWQgPSBuZXcgdHlwZV9rZXlpZCgpO1xuICB0aGlzLm5vdGF0aW9uID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zID0gbnVsbDtcbiAgdGhpcy5rZXlTZXJ2ZXJQcmVmZXJlbmNlcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkS2V5U2VydmVyID0gbnVsbDtcbiAgdGhpcy5pc1ByaW1hcnlVc2VySUQgPSBudWxsO1xuICB0aGlzLnBvbGljeVVSSSA9IG51bGw7XG4gIHRoaXMua2V5RmxhZ3MgPSBudWxsO1xuICB0aGlzLnNpZ25lcnNVc2VySWQgPSBudWxsO1xuICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnID0gbnVsbDtcbiAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nID0gbnVsbDtcbiAgdGhpcy5mZWF0dXJlcyA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoID0gbnVsbDtcbiAgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG51bGw7XG5cbiAgdGhpcy52ZXJpZmllZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBwYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyAyKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIHBheWxvYWQgb2YgYSB0YWcgMiBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGJ5dGVzIHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBieXRlcyBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHttb2R1bGU6cGFja2V0L3NpZ25hdHVyZX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBpID0gMDtcblxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNClcbiAgICBzd2l0Y2ggKHRoaXMudmVyc2lvbikge1xuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuIE1VU1QgYmUgNS5cbiAgICAgICAgaWYgKGJ5dGVzLmNoYXJDb2RlQXQoaSsrKSAhPSA1KVxuICAgICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJwYWNrZXQvc2lnbmF0dXJlLmpzXFxuXCIgK1xuICAgICAgICAgICAgJ2ludmFsaWQgT25lLW9jdGV0IGxlbmd0aCBvZiBmb2xsb3dpbmcgaGFzaGVkIG1hdGVyaWFsLicgK1xuICAgICAgICAgICAgJ01VU1QgYmUgNS4gQDonICsgKGkgLSAxKSk7XG5cbiAgICAgICAgdmFyIHNpZ3BvcyA9IGk7XG4gICAgICAgIC8vIE9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVUeXBlID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICAgIC8vIEZvdXItb2N0ZXQgY3JlYXRpb24gdGltZS5cbiAgICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIoaSwgNCkpO1xuICAgICAgICBpICs9IDQ7XG5cbiAgICAgICAgLy8gc3RvcmluZyBkYXRhIGFwcGVuZGVkIHRvIGRhdGEgd2hpY2ggZ2V0cyB2ZXJpZmllZFxuICAgICAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSBieXRlcy5zdWJzdHJpbmcoc2lncG9zLCBpKTtcblxuICAgICAgICAvLyBFaWdodC1vY3RldCBLZXkgSUQgb2Ygc2lnbmVyLlxuICAgICAgICB0aGlzLmlzc3VlcktleUlkLnJlYWQoYnl0ZXMuc3Vic3RyaW5nKGksIGkgKyA4KSk7XG4gICAgICAgIGkgKz0gODtcblxuICAgICAgICAvLyBPbmUtb2N0ZXQgcHVibGljLWtleSBhbGdvcml0aG0uXG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICAgIC8vIE9uZS1vY3RldCBoYXNoIGFsZ29yaXRobS5cbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgdGhpcy5zaWduYXR1cmVUeXBlID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgdGhpcy5oYXNoQWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICAgIGZ1bmN0aW9uIHN1YnBhY2tldHMoYnl0ZXMpIHtcbiAgICAgICAgICAvLyBUd28tb2N0ZXQgc2NhbGFyIG9jdGV0IGNvdW50IGZvciBmb2xsb3dpbmcgc3VicGFja2V0IGRhdGEuXG4gICAgICAgICAgdmFyIHN1YnBhY2tldF9sZW5ndGggPSB1dGlsLnJlYWROdW1iZXIoXG4gICAgICAgICAgICBieXRlcy5zdWJzdHIoMCwgMikpO1xuXG4gICAgICAgICAgdmFyIGkgPSAyO1xuXG4gICAgICAgICAgLy8gc3VicGFja2V0IGRhdGEgc2V0ICh6ZXJvIG9yIG1vcmUgc3VicGFja2V0cylcbiAgICAgICAgICB2YXIgc3VicGFja2VkX3JlYWQgPSAwO1xuICAgICAgICAgIHdoaWxlIChpIDwgMiArIHN1YnBhY2tldF9sZW5ndGgpIHtcblxuICAgICAgICAgICAgdmFyIGxlbiA9IHBhY2tldC5yZWFkU2ltcGxlTGVuZ3RoKGJ5dGVzLnN1YnN0cihpKSk7XG4gICAgICAgICAgICBpICs9IGxlbi5vZmZzZXQ7XG5cbiAgICAgICAgICAgIHRoaXMucmVhZF9zdWJfcGFja2V0KGJ5dGVzLnN1YnN0cihpLCBsZW4ubGVuKSk7XG5cbiAgICAgICAgICAgIGkgKz0gbGVuLmxlbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhhc2hlZCBzdWJwYWNrZXRzXG4gICAgICAgIGkgKz0gc3VicGFja2V0cy5jYWxsKHRoaXMsIGJ5dGVzLnN1YnN0cihpKSwgdHJ1ZSk7XG5cbiAgICAgICAgLy8gQSBWNCBzaWduYXR1cmUgaGFzaGVzIHRoZSBwYWNrZXQgYm9keVxuICAgICAgICAvLyBzdGFydGluZyBmcm9tIGl0cyBmaXJzdCBmaWVsZCwgdGhlIHZlcnNpb24gbnVtYmVyLCB0aHJvdWdoIHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIGhhc2hlZCBzdWJwYWNrZXQgZGF0YS4gIFRodXMsIHRoZSBmaWVsZHMgaGFzaGVkIGFyZSB0aGVcbiAgICAgICAgLy8gc2lnbmF0dXJlIHZlcnNpb24sIHRoZSBzaWduYXR1cmUgdHlwZSwgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtLCB0aGVcbiAgICAgICAgLy8gaGFzaCBhbGdvcml0aG0sIHRoZSBoYXNoZWQgc3VicGFja2V0IGxlbmd0aCwgYW5kIHRoZSBoYXNoZWRcbiAgICAgICAgLy8gc3VicGFja2V0IGJvZHkuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSA9IGJ5dGVzLnN1YnN0cigwLCBpKTtcblxuICAgICAgICAvLyB1bmhhc2hlZCBzdWJwYWNrZXRzXG4gICAgICAgIGkgKz0gc3VicGFja2V0cy5jYWxsKHRoaXMsIGJ5dGVzLnN1YnN0cihpKSwgZmFsc2UpO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uICcgKyB2ZXJzaW9uICsgJyBvZiB0aGUgc2lnbmF0dXJlIGlzIHVuc3VwcG9ydGVkLicpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBUd28tb2N0ZXQgZmllbGQgaG9sZGluZyBsZWZ0IDE2IGJpdHMgb2Ygc2lnbmVkIGhhc2ggdmFsdWUuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBieXRlcy5zdWJzdHIoaSwgMik7XG4gICAgaSArPSAyO1xuXG4gICAgdGhpcy5zaWduYXR1cmUgPSBieXRlcy5zdWJzdHIoaSk7XG4gIH07XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnNpZ25hdHVyZURhdGEgK1xuICAgICAgdXRpbC53cml0ZU51bWJlcigwLCAyKSArIC8vIE51bWJlciBvZiB1bnNpZ25lZCBzdWJwYWNrZXRzLlxuICAgICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgK1xuICAgICAgdGhpcy5zaWduYXR1cmU7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNpZ25zIHByb3ZpZGVkIGRhdGEuIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBwcmlvciB0byBzZXJpYWxpemF0aW9uLlxuICAgKiBAcGFyYW0ge21vZHVsZTpwYWNrZXQvc2VjcmV0X2tleX0ga2V5IHByaXZhdGUga2V5IHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZS4gXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIENvbnRhaW5zIHBhY2tldHMgdG8gYmUgc2lnbmVkLlxuICAgKi9cbiAgdGhpcy5zaWduID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lnbmF0dXJlVHlwZSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocHVibGljS2V5QWxnb3JpdGhtKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoQWxnb3JpdGhtKTtcblxuICAgIHRoaXMuaXNzdWVyS2V5SWQgPSBrZXkuZ2V0S2V5SWQoKTtcblxuICAgIC8vIEFkZCBoYXNoZWQgc3VicGFja2V0c1xuICAgIHJlc3VsdCArPSB0aGlzLndyaXRlX2FsbF9zdWJfcGFja2V0cygpO1xuXG4gICAgdGhpcy5zaWduYXR1cmVEYXRhID0gcmVzdWx0O1xuXG4gICAgdmFyIHRyYWlsZXIgPSB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIoKTtcblxuICAgIHZhciB0b0hhc2ggPSB0aGlzLnRvU2lnbihzaWduYXR1cmVUeXBlLCBkYXRhKSArXG4gICAgICB0aGlzLnNpZ25hdHVyZURhdGEgKyB0cmFpbGVyO1xuXG4gICAgdmFyIGhhc2ggPSBjcnlwdG8uaGFzaC5kaWdlc3QoaGFzaEFsZ29yaXRobSwgdG9IYXNoKTtcblxuICAgIHRoaXMuc2lnbmVkSGFzaFZhbHVlID0gaGFzaC5zdWJzdHIoMCwgMik7XG5cbiAgICB0aGlzLnNpZ25hdHVyZSA9IGNyeXB0by5zaWduYXR1cmUuc2lnbihoYXNoQWxnb3JpdGhtLFxuICAgICAgcHVibGljS2V5QWxnb3JpdGhtLCBrZXkubXBpLCB0b0hhc2gpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHN0cmluZyBvZiBieXRlcyB3aXRoIGFsbCBzdWJwYWNrZXQgZGF0YVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIGEgYWxsIHN1YnBhY2tldCBkYXRhXG4gICAqL1xuICB0aGlzLndyaXRlX2FsbF9zdWJfcGFja2V0cyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdWIgPSBlbnVtcy5zaWduYXR1cmVTdWJwYWNrZXQ7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIHZhciBieXRlcyA9ICcnO1xuICAgIGlmICh0aGlzLmNyZWF0ZWQgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5zaWduYXR1cmVfY3JlYXRpb25fdGltZSwgdXRpbC53cml0ZURhdGUodGhpcy5jcmVhdGVkKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuc2lnbmF0dXJlX2V4cGlyYXRpb25fdGltZSwgdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lLCA0KSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmV4cG9ydGFibGUgIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5leHBvcnRhYmxlX2NlcnRpZmljYXRpb24sIFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5leHBvcnRhYmxlID8gMSA6IDApKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudHJ1c3RMZXZlbCAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RMZXZlbCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudHJ1c3RBbW91bnQpO1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnRydXN0X3NpZ25hdHVyZSwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWd1bGFyRXhwcmVzc2lvbiAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJlZ3VsYXJfZXhwcmVzc2lvbiwgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbik7XG4gICAgfVxuICAgIGlmICh0aGlzLnJldm9jYWJsZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJldm9jYWJsZSwgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnJldm9jYWJsZSA/IDEgOiAwKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmtleUV4cGlyYXRpb25UaW1lICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIua2V5X2V4cGlyYXRpb25fdGltZSwgdXRpbC53cml0ZU51bWJlcih0aGlzLmtleUV4cGlyYXRpb25UaW1lLCA0KSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJlZmVycmVkX3N5bW1ldHJpY19hbGdvcml0aG1zLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnJldm9jYXRpb25LZXlDbGFzcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmV2b2NhdGlvbktleUNsYXNzKTtcbiAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtKTtcbiAgICAgIGJ5dGVzICs9IHRoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50O1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnJldm9jYXRpb25fa2V5LCBieXRlcyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc3N1ZXJLZXlJZC5pc051bGwoKSkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmlzc3VlciwgdGhpcy5pc3N1ZXJLZXlJZC53cml0ZSgpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMubm90YXRpb24gIT09IG51bGwpIHtcbiAgICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcy5ub3RhdGlvbikge1xuICAgICAgICBpZiAodGhpcy5ub3RhdGlvbi5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubm90YXRpb25bbmFtZV07XG4gICAgICAgICAgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODApO1xuICAgICAgICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgICAgIC8vIDIgb2N0ZXRzIG9mIG5hbWUgbGVuZ3RoXG4gICAgICAgICAgYnl0ZXMgKz0gdXRpbC53cml0ZU51bWJlcihuYW1lLmxlbmd0aCwgMik7XG4gICAgICAgICAgLy8gMiBvY3RldHMgb2YgdmFsdWUgbGVuZ3RoXG4gICAgICAgICAgYnl0ZXMgKz0gdXRpbC53cml0ZU51bWJlcih2YWx1ZS5sZW5ndGgsIDIpO1xuICAgICAgICAgIGJ5dGVzICs9IG5hbWUgKyB2YWx1ZTtcbiAgICAgICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIubm90YXRpb25fZGF0YSwgYnl0ZXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBcbiAgICBpZiAodGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcyAhPT0gbnVsbCkge1xuICAgICAgYnl0ZXMgPSB1dGlsLmJpbjJzdHIodGhpcy5wcmVmZXJyZWRIYXNoQWxnb3JpdGhtcyk7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucHJlZmVycmVkX2hhc2hfYWxnb3JpdGhtcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gdXRpbC5iaW4yc3RyKHRoaXMucHJlZmVycmVkQ29tcHJlc3Npb25BbGdvcml0aG1zKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5wcmVmZXJyZWRfaGFzaF9hbGdvcml0aG1zLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmtleVNlcnZlclByZWZlcmVuY2VzICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLmtleVNlcnZlclByZWZlcmVuY2VzKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5rZXlfc2VydmVyX3ByZWZlcmVuY2VzLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnByZWZlcnJlZEtleVNlcnZlciAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByZWZlcnJlZF9rZXlfc2VydmVyLCB0aGlzLnByZWZlcnJlZEtleVNlcnZlcik7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzUHJpbWFyeVVzZXJJRCAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnByaW1hcnlfdXNlcl9pZCwgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmlzUHJpbWFyeVVzZXJJRCA/IDEgOiAwKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBvbGljeVVSSSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnBvbGljeV91cmksIHRoaXMucG9saWN5VVJJKTsgXG4gICAgfVxuICAgIGlmICh0aGlzLmtleUZsYWdzICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLmtleUZsYWdzKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5rZXlfZmxhZ3MsIGJ5dGVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2lnbmVyc1VzZXJJZCAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLnNpZ25lcnNfdXNlcl9pZCwgdGhpcy5zaWduZXJzVXNlcklkKTsgXG4gICAgfVxuICAgIGlmICh0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyk7XG4gICAgICBieXRlcyArPSB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmc7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIucmVhc29uX2Zvcl9yZXZvY2F0aW9uLCBieXRlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmZlYXR1cmVzICE9PSBudWxsKSB7XG4gICAgICBieXRlcyA9IHV0aWwuYmluMnN0cih0aGlzLmZlYXR1cmVzKTtcbiAgICAgIHJlc3VsdCArPSB3cml0ZV9zdWJfcGFja2V0KHN1Yi5mZWF0dXJlcywgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0gIT09IG51bGwpIHtcbiAgICAgIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSk7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSk7XG4gICAgICBieXRlcyArPSB0aGlzLnNpZ25hdHVyZVRhcmdldEhhc2g7XG4gICAgICByZXN1bHQgKz0gd3JpdGVfc3ViX3BhY2tldChzdWIuc2lnbmF0dXJlX3RhcmdldCwgYnl0ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5lbWJlZGRlZFNpZ25hdHVyZSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0ICs9IHdyaXRlX3N1Yl9wYWNrZXQoc3ViLmVtYmVkZGVkX3NpZ25hdHVyZSwgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZS53cml0ZSgpKTtcbiAgICB9XG4gICAgcmVzdWx0ID0gdXRpbC53cml0ZU51bWJlcihyZXN1bHQubGVuZ3RoLCAyKSArIHJlc3VsdDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHR5cGUgc3VicGFja2V0IHNpZ25hdHVyZSB0eXBlLiBTaWduYXR1cmUgdHlwZXMgYXMgZGVzY3JpYmVkIFxuICAgKiBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjMuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBkYXRhIHRvIGJlIGluY2x1ZGVkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgYSBzdWIgc2lnbmF0dXJlIHBhY2tldCAoU2VlIFJGQyA0ODgwIDUuMi4zLjEpXG4gICAqL1xuICBmdW5jdGlvbiB3cml0ZV9zdWJfcGFja2V0KHR5cGUsIGRhdGEpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICByZXN1bHQgKz0gcGFja2V0LndyaXRlU2ltcGxlTGVuZ3RoKGRhdGEubGVuZ3RoICsgMSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZSk7XG4gICAgcmVzdWx0ICs9IGRhdGE7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIFY0IHNpZ25hdHVyZSBzdWIgcGFja2V0c1xuXG4gIHRoaXMucmVhZF9zdWJfcGFja2V0ID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbXlwb3MgPSAwO1xuXG4gICAgZnVuY3Rpb24gcmVhZF9hcnJheShwcm9wLCBieXRlcykge1xuICAgICAgdGhpc1twcm9wXSA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbcHJvcF0ucHVzaChieXRlcy5jaGFyQ29kZUF0KGkpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGUgbGVmdHdvc3QgYml0IGRlbm90ZXMgYSBcImNyaXRpY2FsXCIgcGFja2V0LCBidXQgd2UgaWdub3JlIGl0LlxuICAgIHZhciB0eXBlID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSAmIDB4N0Y7XG5cbiAgICAvLyBzdWJwYWNrZXQgdHlwZVxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAyOlxuICAgICAgICAvLyBTaWduYXR1cmUgQ3JlYXRpb24gVGltZVxuICAgICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gU2lnbmF0dXJlIEV4cGlyYXRpb24gVGltZSBpbiBzZWNvbmRzXG4gICAgICAgIHZhciBzZWNvbmRzID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gc2Vjb25kcyA9PSAwO1xuICAgICAgICB0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lID0gc2Vjb25kcztcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgLy8gRXhwb3J0YWJsZSBDZXJ0aWZpY2F0aW9uXG4gICAgICAgIHRoaXMuZXhwb3J0YWJsZSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykgPT0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIC8vIFRydXN0IFNpZ25hdHVyZVxuICAgICAgICB0aGlzLnRydXN0TGV2ZWwgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgICAgICB0aGlzLnRydXN0QW1vdW50ID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIC8vIFJlZ3VsYXIgRXhwcmVzc2lvblxuICAgICAgICB0aGlzLnJlZ3VsYXJFeHByZXNzaW9uID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDc6XG4gICAgICAgIC8vIFJldm9jYWJsZVxuICAgICAgICB0aGlzLnJldm9jYWJsZSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykgPT0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIEtleSBFeHBpcmF0aW9uIFRpbWUgaW4gc2Vjb25kc1xuICAgICAgICB2YXIgc2Vjb25kcyA9IHV0aWwucmVhZE51bWJlcihieXRlcy5zdWJzdHIobXlwb3MpKTtcblxuICAgICAgICB0aGlzLmtleUV4cGlyYXRpb25UaW1lID0gc2Vjb25kcztcbiAgICAgICAgdGhpcy5rZXlOZXZlckV4cGlyZXMgPSBzZWNvbmRzID09IDA7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDExOlxuICAgICAgICAvLyBQcmVmZXJyZWQgU3ltbWV0cmljIEFsZ29yaXRobXNcbiAgICAgICAgdGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zID0gW107XG5cbiAgICAgICAgd2hpbGUgKG15cG9zICE9IGJ5dGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcy5wdXNoKGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyOlxuICAgICAgICAvLyBSZXZvY2F0aW9uIEtleVxuICAgICAgICAvLyAoMSBvY3RldCBvZiBjbGFzcywgMSBvY3RldCBvZiBwdWJsaWMta2V5IGFsZ29yaXRobSBJRCwgMjBcbiAgICAgICAgLy8gb2N0ZXRzIG9mXG4gICAgICAgIC8vIGZpbmdlcnByaW50KVxuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlDbGFzcyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMucmV2b2NhdGlvbktleUFsZ29yaXRobSA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50ID0gYnl0ZXMuc3Vic3RyKG15cG9zLCAyMCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBJc3N1ZXJcbiAgICAgICAgdGhpcy5pc3N1ZXJLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAyMDpcbiAgICAgICAgLy8gTm90YXRpb24gRGF0YVxuICAgICAgICAvLyBXZSBkb24ndCBrbm93IGhvdyB0byBoYW5kbGUgYW55dGhpbmcgYnV0IGEgdGV4dCBmbGFnZ2VkIGRhdGEuXG4gICAgICAgIGlmIChieXRlcy5jaGFyQ29kZUF0KG15cG9zKSA9PSAweDgwKSB7XG5cbiAgICAgICAgICAvLyBXZSBleHRyYWN0IGtleS92YWx1ZSB0dXBsZSBmcm9tIHRoZSBieXRlIHN0cmVhbS5cbiAgICAgICAgICBteXBvcyArPSA0O1xuICAgICAgICAgIHZhciBtID0gdXRpbC5yZWFkTnVtYmVyKGJ5dGVzLnN1YnN0cihteXBvcywgMikpO1xuICAgICAgICAgIG15cG9zICs9IDJcbiAgICAgICAgICB2YXIgbiA9IHV0aWwucmVhZE51bWJlcihieXRlcy5zdWJzdHIobXlwb3MsIDIpKTtcbiAgICAgICAgICBteXBvcyArPSAyXG5cbiAgICAgICAgICB2YXIgbmFtZSA9IGJ5dGVzLnN1YnN0cihteXBvcywgbSksXG4gICAgICAgICAgICB2YWx1ZSA9IGJ5dGVzLnN1YnN0cihteXBvcyArIG0sIG4pO1xuXG4gICAgICAgICAgdGhpcy5ub3RhdGlvbiA9IHRoaXMubm90YXRpb24gfHwge307XG4gICAgICAgICAgdGhpcy5ub3RhdGlvbltuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgbm90YXRpb24gZmxhZy5cIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMTpcbiAgICAgICAgLy8gUHJlZmVycmVkIEhhc2ggQWxnb3JpdGhtc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ3ByZWZlcnJlZEhhc2hBbGdvcml0aG1zJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMjpcbiAgICAgICAgLy8gUHJlZmVycmVkIENvbXByZXNzaW9uIEFsZ29yaXRobXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdwcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMzpcbiAgICAgICAgLy8gS2V5IFNlcnZlciBQcmVmZXJlbmNlc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2tleVNlcnZlclByZWZlcmVuY2VzcycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjQ6XG4gICAgICAgIC8vIFByZWZlcnJlZCBLZXkgU2VydmVyXG4gICAgICAgIHRoaXMucHJlZmVycmVkS2V5U2VydmVyID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI1OlxuICAgICAgICAvLyBQcmltYXJ5IFVzZXIgSURcbiAgICAgICAgdGhpcy5pc1ByaW1hcnlVc2VySUQgPSBieXRlc1tteXBvcysrXSAhPSAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjY6XG4gICAgICAgIC8vIFBvbGljeSBVUklcbiAgICAgICAgdGhpcy5wb2xpY3lVUkkgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjc6XG4gICAgICAgIC8vIEtleSBGbGFnc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2tleUZsYWdzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyODpcbiAgICAgICAgLy8gU2lnbmVyJ3MgVXNlciBJRFxuICAgICAgICB0aGlzLnNpZ25lcnNVc2VySWQgKz0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI5OlxuICAgICAgICAvLyBSZWFzb24gZm9yIFJldm9jYXRpb25cbiAgICAgICAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG4gICAgICAgIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvblN0cmluZyA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMDpcbiAgICAgICAgLy8gRmVhdHVyZXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdmZWF0dXJlcycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzE6XG4gICAgICAgIC8vIFNpZ25hdHVyZSBUYXJnZXRcbiAgICAgICAgLy8gKDEgb2N0ZXQgcHVibGljLWtleSBhbGdvcml0aG0sIDEgb2N0ZXQgaGFzaCBhbGdvcml0aG0sIE4gb2N0ZXRzIGhhc2gpXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcbiAgICAgICAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcblxuICAgICAgICB2YXIgbGVuID0gY3J5cHRvLmdldEhhc2hCeXRlTGVuZ3RoKHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSk7XG5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoID0gYnl0ZXMuc3Vic3RyKG15cG9zLCBsZW4pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzI6XG4gICAgICAgIC8vIEVtYmVkZGVkIFNpZ25hdHVyZVxuICAgICAgICB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlID0gbmV3IHBhY2tldFNpZ25hdHVyZSgpO1xuICAgICAgICB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLnJlYWQoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzaWduYXR1cmUgc3VicGFja2V0IHR5cGUgXCIgKyB0eXBlICsgXCIgQDpcIiArIG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9O1xuXG4gIC8vIFByb2R1Y2VzIGRhdGEgdG8gcHJvZHVjZSBzaWduYXR1cmUgb25cbiAgdGhpcy50b1NpZ24gPSBmdW5jdGlvbih0eXBlLCBkYXRhKSB7XG4gICAgdmFyIHQgPSBlbnVtcy5zaWduYXR1cmU7XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgdC5iaW5hcnk6XG4gICAgICBjYXNlIHQudGV4dDpcbiAgICAgICAgcmV0dXJuIGRhdGEuZ2V0Qnl0ZXMoKTtcblxuICAgICAgY2FzZSB0LnN0YW5kYWxvbmU6XG4gICAgICAgIHJldHVybiAnJztcblxuICAgICAgY2FzZSB0LmNlcnRfZ2VuZXJpYzpcbiAgICAgIGNhc2UgdC5jZXJ0X3BlcnNvbmE6XG4gICAgICBjYXNlIHQuY2VydF9jYXN1YWw6XG4gICAgICBjYXNlIHQuY2VydF9wb3NpdGl2ZTpcbiAgICAgIGNhc2UgdC5jZXJ0X3Jldm9jYXRpb246XG4gICAgICAgIHZhciBwYWNrZXQsIHRhZztcblxuICAgICAgICBpZiAoZGF0YS51c2VyaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRhZyA9IDB4QjQ7XG4gICAgICAgICAgcGFja2V0ID0gZGF0YS51c2VyaWQ7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YS51c2VyYXR0cmlidXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0YWcgPSAweEQxO1xuICAgICAgICAgIHBhY2tldCA9IGRhdGEudXNlcmF0dHJpYnV0ZTtcbiAgICAgICAgfSBlbHNlIHRocm93IG5ldyBFcnJvcignRWl0aGVyIGEgdXNlcmlkIG9yIHVzZXJhdHRyaWJ1dGUgcGFja2V0IG5lZWRzIHRvIGJlICcgK1xuICAgICAgICAgICAgJ3N1cHBsaWVkIGZvciBjZXJ0aWZpY2F0aW9uLicpO1xuXG4gICAgICAgIHZhciBieXRlcyA9IHBhY2tldC53cml0ZSgpO1xuXG4gICAgICAgIGlmICh0aGlzLnZlcnNpb24gPT0gNCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSkgK1xuICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUodGFnKSArXG4gICAgICAgICAgdXRpbC53cml0ZU51bWJlcihieXRlcy5sZW5ndGgsIDQpICtcbiAgICAgICAgICBieXRlczsgXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy52ZXJzaW9uID09IDMpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICtcbiAgICAgICAgICBieXRlcztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSB0LnN1YmtleV9iaW5kaW5nOlxuICAgICAgY2FzZSB0LmtleV9iaW5kaW5nOlxuICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICsgdGhpcy50b1NpZ24odC5rZXksIHtcbiAgICAgICAgICBrZXk6IGRhdGEuYmluZFxuICAgICAgICB9KTtcblxuICAgICAgY2FzZSB0LmtleTpcbiAgICAgICAgaWYgKGRhdGEua2V5ID09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0tleSBwYWNrZXQgaXMgcmVxdWlyZWQgZm9yIHRoaXMgc2lndGF0dXJlLicpO1xuXG4gICAgICAgIHJldHVybiBkYXRhLmtleS53cml0ZU9sZCgpO1xuXG4gICAgICBjYXNlIHQua2V5X3Jldm9jYXRpb246XG4gICAgICBjYXNlIHQuc3Via2V5X3Jldm9jYXRpb246XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSk7XG4gICAgICBjYXNlIHQudGltZXN0YW1wOlxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICBjYXNlIHQudGhpcmRfcGFydHk6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHNpZ25hdHVyZSB0eXBlLicpXG4gICAgfVxuICB9XG5cblxuICB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlclxuICAgIHZhciB0cmFpbGVyID0gJyc7XG4gICAgLy8gVjMgc2lnbmF0dXJlcyBkb24ndCBoYXZlIGEgdHJhaWxlclxuICAgIGlmICh0aGlzLnZlcnNpb24gPT0gMykgcmV0dXJuIHRyYWlsZXI7XG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOyAvLyBWZXJzaW9uXG4gICAgdHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpO1xuICAgIHRyYWlsZXIgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZURhdGEubGVuZ3RoLCA0KTtcbiAgICByZXR1cm4gdHJhaWxlclxuICB9XG5cblxuICAvKipcbiAgICogdmVyaWZ5cyB0aGUgc2lnbmF0dXJlIHBhY2tldC4gTm90ZTogbm90IHNpZ25hdHVyZSB0eXBlcyBhcmUgaW1wbGVtZW50ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBkYXRhIGRhdGEgd2hpY2ggb24gdGhlIHNpZ25hdHVyZSBhcHBsaWVzXG4gICAqIEBwYXJhbSB7bW9kdWxlOnBhY2tldC9wdWJsaWNfc3Via2V5fG1vZHVsZTpwYWNrZXQvcHVibGljX2tleX0ga2V5IHRoZSBwdWJsaWMga2V5IHRvIHZlcmlmeSB0aGUgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbWVzc2FnZSBpcyB2ZXJpZmllZCwgZWxzZSBmYWxzZS5cbiAgICovXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIGJ5dGVzID0gdGhpcy50b1NpZ24oc2lnbmF0dXJlVHlwZSwgZGF0YSksXG4gICAgICB0cmFpbGVyID0gdGhpcy5jYWxjdWxhdGVUcmFpbGVyKCk7XG5cblxuICAgIHZhciBtcGljb3VudCA9IDA7XG4gICAgLy8gQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgUlNBIHNpZ25hdHVyZXM6XG4gICAgLy8gICAgICAtIG11bHRpcHJlY2lzaW9uIG51bWJlciAoTVBJKSBvZiBSU0Egc2lnbmF0dXJlIHZhbHVlIG0qKmQgbW9kIG4uXG4gICAgaWYgKHB1YmxpY0tleUFsZ29yaXRobSA+IDAgJiYgcHVibGljS2V5QWxnb3JpdGhtIDwgNClcbiAgICAgIG1waWNvdW50ID0gMTtcbiAgICAvLyAgICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2lnbmF0dXJlczpcbiAgICAvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSByLlxuICAgIC8vICAgICAgLSBNUEkgb2YgRFNBIHZhbHVlIHMuXG4gICAgZWxzZSBpZiAocHVibGljS2V5QWxnb3JpdGhtID09IDE3KVxuICAgICAgbXBpY291bnQgPSAyO1xuXG4gICAgdmFyIG1waSA9IFtdLFxuICAgICAgaSA9IDA7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBtcGljb3VudDsgaisrKSB7XG4gICAgICBtcGlbal0gPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGkgKz0gbXBpW2pdLnJlYWQodGhpcy5zaWduYXR1cmUuc3Vic3RyKGkpKTtcbiAgICB9XG5cbiAgICB0aGlzLnZlcmlmaWVkID0gY3J5cHRvLnNpZ25hdHVyZS52ZXJpZnkocHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAgaGFzaEFsZ29yaXRobSwgbXBpLCBrZXkubXBpLFxuICAgICAgYnl0ZXMgKyB0aGlzLnNpZ25hdHVyZURhdGEgKyB0cmFpbGVyKTtcblxuICAgIHJldHVybiB0aGlzLnZlcmlmaWVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHNpZ25hdHVyZSBleHBpcmF0aW9uIGRhdGVcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiBleHBpcmVkXG4gICAqL1xuICB0aGlzLmlzRXhwaXJlZCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICghdGhpcy5zaWduYXR1cmVOZXZlckV4cGlyZXMpIHtcbiAgICAgIHJldHVybiBEYXRlLm5vdygpID4gKHRoaXMuY3JlYXRlZC5nZXRUaW1lKCkgKyB0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lKjEwMDApO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFN5bS4gRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YVxuICogUGFja2V0IChUYWcgMTgpPGJyLz5cbiAqIDxici8+XG4gKiBSRkM0ODgwIDUuMTM6IFRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBJbnRlZ3JpdHkgUHJvdGVjdGVkIERhdGEgcGFja2V0IGlzXG4gKiBhIHZhcmlhbnQgb2YgdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0LiBJdCBpcyBhIG5ldyBmZWF0dXJlXG4gKiBjcmVhdGVkIGZvciBPcGVuUEdQIHRoYXQgYWRkcmVzc2VzIHRoZSBwcm9ibGVtIG9mIGRldGVjdGluZyBhIG1vZGlmaWNhdGlvbiB0b1xuICogZW5jcnlwdGVkIGRhdGEuIEl0IGlzIHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBhIE1vZGlmaWNhdGlvbiBEZXRlY3Rpb24gQ29kZVxuICogcGFja2V0LlxuICogQHJlcXVpcmVzIGNyeXB0b1xuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgcGFja2V0L3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZFxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKiBUaGUgZW5jcnlwdGVkIHBheWxvYWQuICovXG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDsgLy8gc3RyaW5nXG4gIC8qKlxuICAgKiBJZiBhZnRlciBkZWNyeXB0aW5nIHRoZSBwYWNrZXQgdGhpcyBpcyBzZXQgdG8gdHJ1ZSxcbiAgICogYSBtb2RpZmljYXRpb24gaGFzIGJlZW4gZGV0ZWN0ZWQgYW5kIHRodXMgdGhlIGNvbnRlbnRzXG4gICAqIHNob3VsZCBiZSBkaXNjYXJkZWQuXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cbiAgdGhpcy5tb2RpZmljYXRpb24gPSBmYWxzZTtcbiAgdGhpcy5wYWNrZXRzID0gbnVsbDtcblxuXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXMgMS5cbiAgICB2YXIgdmVyc2lvbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMCk7XG5cbiAgICBpZiAodmVyc2lvbiAhPSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcGFja2V0IHZlcnNpb24uJyk7XG4gICAgfVxuXG4gICAgLy8gLSBFbmNyeXB0ZWQgZGF0YSwgdGhlIG91dHB1dCBvZiB0aGUgc2VsZWN0ZWQgc3ltbWV0cmljLWtleSBjaXBoZXJcbiAgICAvLyAgIG9wZXJhdGluZyBpbiBDaXBoZXIgRmVlZGJhY2sgbW9kZSB3aXRoIHNoaWZ0IGFtb3VudCBlcXVhbCB0byB0aGVcbiAgICAvLyAgIGJsb2NrIHNpemUgb2YgdGhlIGNpcGhlciAoQ0ZCLW4gd2hlcmUgbiBpcyB0aGUgYmxvY2sgc2l6ZSkuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBieXRlcy5zdWJzdHIoMSk7XG4gIH07XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMSkgLy8gVmVyc2lvblxuICAgICsgdGhpcy5lbmNyeXB0ZWQ7XG4gIH07XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzLndyaXRlKClcblxuICAgIHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuICAgIHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtXG4gICAgICAxKVxuXG4gICAgdmFyIHRvaGFzaCA9IGJ5dGVzO1xuXG5cbiAgICAvLyBNb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0LlxuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RDMpO1xuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTQpO1xuXG5cbiAgICB0b2hhc2ggKz0gY3J5cHRvLmhhc2guc2hhMShwcmVmaXggKyB0b2hhc2gpO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChwcmVmaXhyYW5kb20sXG4gICAgICBzZXNzaW9uS2V5QWxnb3JpdGhtLCB0b2hhc2gsIGtleSwgZmFsc2UpLnN1YnN0cmluZygwLFxuICAgICAgcHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgZW5jcnlwdGVkIGRhdGEgY29udGFpbmVkIGluIHRoaXMgb2JqZWN0IHJlYWRfcGFja2V0IG11c3RcbiAgICogaGF2ZSBiZWVuIGNhbGxlZCBiZWZvcmVcbiAgICogXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc2Vzc2lvbktleUFsZ29yaXRobVxuICAgKiAgICAgICAgICAgIFRoZSBzZWxlY3RlZCBzeW1tZXRyaWMgZW5jcnlwdGlvbiBhbGdvcml0aG0gdG8gYmUgdXNlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSBrZXkgb2YgY2lwaGVyIGJsb2Nrc2l6ZSBsZW5ndGggdG8gYmUgdXNlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBkZWNyeXB0ZWQgZGF0YSBvZiB0aGlzIHBhY2tldFxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcbiAgICAgIHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQsIGZhbHNlKTtcblxuXG4gICAgLy8gdGhlcmUgbXVzdCBiZSBhIG1vZGlmaWNhdGlvbiBkZXRlY3Rpb24gY29kZSBwYWNrZXQgYXMgdGhlXG4gICAgLy8gbGFzdCBwYWNrZXQgYW5kIGV2ZXJ5dGhpbmcgZ2V0cyBoYXNoZWQgZXhjZXB0IHRoZSBoYXNoIGl0c2VsZlxuICAgIHRoaXMuaGFzaCA9IGNyeXB0by5oYXNoLnNoYTEoXG4gICAgICBjcnlwdG8uY2ZiLm1kYyhzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXksIHRoaXMuZW5jcnlwdGVkKSArIGRlY3J5cHRlZC5zdWJzdHJpbmcoMCwgZGVjcnlwdGVkLmxlbmd0aCAtIDIwKSk7XG5cblxuICAgIHZhciBtZGMgPSBkZWNyeXB0ZWQuc3Vic3RyKGRlY3J5cHRlZC5sZW5ndGggLSAyMCwgMjApO1xuXG4gICAgaWYgKHRoaXMuaGFzaCAhPSBtZGMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTW9kaWZpY2F0aW9uIGRldGVjdGVkLicpO1xuICAgIH0gZWxzZVxuICAgICAgdGhpcy5wYWNrZXRzLnJlYWQoZGVjcnlwdGVkLnN1YnN0cigwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjIpKTtcbiAgfTtcbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAxKTxici8+XG4gKiA8YnIvPlxuICogUkZDNDg4MCA1LjE6IEEgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0IGhvbGRzIHRoZSBzZXNzaW9uIGtleVxuICogdXNlZCB0byBlbmNyeXB0IGEgbWVzc2FnZS4gWmVybyBvciBtb3JlIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5XG4gKiBwYWNrZXRzIGFuZC9vciBTeW1tZXRyaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXRzIG1heSBwcmVjZWRlIGFcbiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0LCB3aGljaCBob2xkcyBhbiBlbmNyeXB0ZWQgbWVzc2FnZS4gVGhlXG4gKiBtZXNzYWdlIGlzIGVuY3J5cHRlZCB3aXRoIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZSBzZXNzaW9uIGtleSBpcyBpdHNlbGZcbiAqIGVuY3J5cHRlZCBhbmQgc3RvcmVkIGluIHRoZSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0KHMpLiBUaGVcbiAqIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgUGFja2V0IGlzIHByZWNlZGVkIGJ5IG9uZSBQdWJsaWMtS2V5IEVuY3J5cHRlZFxuICogU2Vzc2lvbiBLZXkgcGFja2V0IGZvciBlYWNoIE9wZW5QR1Aga2V5IHRvIHdoaWNoIHRoZSBtZXNzYWdlIGlzIGVuY3J5cHRlZC5cbiAqIFRoZSByZWNpcGllbnQgb2YgdGhlIG1lc3NhZ2UgZmluZHMgYSBzZXNzaW9uIGtleSB0aGF0IGlzIGVuY3J5cHRlZCB0byB0aGVpclxuICogcHVibGljIGtleSwgZGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlbiB1c2VzIHRoZSBzZXNzaW9uIGtleSB0b1xuICogZGVjcnlwdCB0aGUgbWVzc2FnZS5cbiAqIEByZXF1aXJlcyBjcnlwdG9cbiAqIEByZXF1aXJlcyBlbnVtc1xuICogQHJlcXVpcmVzIHR5cGUvczJrXG4gKiBAbW9kdWxlIHBhY2tldC9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5XG4gKi9cblxudmFyIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudGFnID0gMztcbiAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIHRoaXMuczJrID0gbmV3IHR5cGVfczJrKCk7XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3ltbWV0cmljIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAzKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge21vZHVsZTpwYWNrZXQvc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiBUaGUgb25seSBjdXJyZW50bHkgZGVmaW5lZCB2ZXJzaW9uIGlzIDQuXG4gICAgdGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdCgwKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBzeW1tZXRyaWMgYWxnb3JpdGhtIHVzZWQuXG4gICAgdmFyIGFsZ28gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgYnl0ZXMuY2hhckNvZGVBdCgxKSk7XG5cbiAgICAvLyBBIHN0cmluZy10by1rZXkgKFMySykgc3BlY2lmaWVyLCBsZW5ndGggYXMgZGVmaW5lZCBhYm92ZS5cbiAgICB2YXIgczJrbGVuZ3RoID0gdGhpcy5zMmsucmVhZChieXRlcy5zdWJzdHIoMikpO1xuXG4gICAgLy8gT3B0aW9uYWxseSwgdGhlIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBpdHNlbGYsIHdoaWNoIGlzIGRlY3J5cHRlZFxuICAgIC8vIHdpdGggdGhlIHN0cmluZy10by1rZXkgb2JqZWN0LlxuICAgIHZhciBkb25lID0gczJrbGVuZ3RoICsgMjtcblxuICAgIGlmIChkb25lIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cihkb25lKTtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gPSBhbGdvXG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSBhbGdvO1xuICB9O1xuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYWxnbyA9IHRoaXMuZW5jcnlwdGVkID09IG51bGwgP1xuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtIDpcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG07XG5cbiAgICB2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMudmVyc2lvbikgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIGFsZ28pKSArXG4gICAgICB0aGlzLnMyay53cml0ZSgpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGVkICE9IG51bGwpXG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICByZXR1cm4gYnl0ZXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSAob25seSBmb3IgcHVibGljIGtleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICogcGFja2V0cyAodGFnIDEpXG4gICAqIFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSB1bmVuY3J5cHRlZCBzZXNzaW9uIGtleVxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICAgIHZhciBhbGdvID0gdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSAhPSBudWxsID9cbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gOlxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtO1xuXG5cbiAgICB2YXIgbGVuZ3RoID0gY3J5cHRvLmNpcGhlclthbGdvXS5rZXlTaXplO1xuICAgIHZhciBrZXkgPSB0aGlzLnMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLCBsZW5ndGgpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGVkID09IG51bGwpIHtcbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGtleTtcblxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtLCBrZXksIHRoaXMuZW5jcnlwdGVkLCB0cnVlKTtcblxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsXG4gICAgICAgIGRlY3J5cHRlZFswXS5rZXlDb2RlQXQoKSk7XG5cbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGRlY3J5cHRlZC5zdWJzdHIoMSk7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcbiAgICB2YXIgbGVuZ3RoID0gY3J5cHRvLmdldEtleUxlbmd0aCh0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtKTtcbiAgICB2YXIga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkocGFzc3BocmFzZSwgbGVuZ3RoKTtcblxuICAgIHZhciBwcml2YXRlX2tleSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpICtcblxuICAgIGNyeXB0by5nZXRSYW5kb21CeXRlcyhcbiAgICAgIGNyeXB0by5nZXRLZXlMZW5ndGgodGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChcbiAgICAgIGNyeXB0by5nZXRQcmVmaXhSYW5kb20odGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSksXG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtLCBrZXksIHByaXZhdGVfa2V5LCB0cnVlKTtcbiAgfTtcbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCAoVGFnIDkpPGJyLz5cbiAqIDxici8+XG4gKiBSRkM0ODgwIDUuNzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0IGNvbnRhaW5zIGRhdGEgZW5jcnlwdGVkXG4gKiB3aXRoIGEgc3ltbWV0cmljLWtleSBhbGdvcml0aG0uIFdoZW4gaXQgaGFzIGJlZW4gZGVjcnlwdGVkLCBpdCBjb250YWlucyBvdGhlclxuICogcGFja2V0cyAodXN1YWxseSBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgb3IgY29tcHJlc3NlZCBkYXRhIHBhY2tldCwgYnV0IGluXG4gKiB0aGVvcnkgb3RoZXIgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXRzIG9yIHNlcXVlbmNlcyBvZiBwYWNrZXRzXG4gKiB0aGF0IGZvcm0gd2hvbGUgT3BlblBHUCBtZXNzYWdlcykuXG4gKiBAcmVxdWlyZXMgY3J5cHRvXG4gKiBAbW9kdWxlIHBhY2tldC9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZFxuICovXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcbiAgLyoqIERlY3J5cHRlZCBwYWNrZXRzIGNvbnRhaW5lZCB3aXRoaW4uIFxuICAgKiBAdHlwZSB7bW9kdWxlOnBhY2tldC9wYWNrZXRsaXN0fSAqL1xuICB0aGlzLnBhY2tldHMgPSAgbnVsbDtcblxuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXM7XG4gIH07XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmVuY3J5cHRlZDtcbiAgfTtcblxuICAvKipcbiAgICogU3ltbWV0cmljYWxseSBkZWNyeXB0IHRoZSBwYWNrZXQgZGF0YVxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG4gICAqICAgICAgICAgICAgIFN5bW1ldHJpYyBrZXkgYWxnb3JpdGhtIHRvIHVzZSAvLyBTZWUgUkZDNDg4MCA5LjJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgKiAgICAgICAgICAgICBLZXkgYXMgc3RyaW5nIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgbGVuZ3RoIHRvIHRoZVxuICAgKiAgICAgICAgICAgIGFsZ29yaXRobVxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcbiAgICAgIHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQsIHRydWUpO1xuXG4gICAgdGhpcy5wYWNrZXRzLnJlYWQoZGVjcnlwdGVkKTtcbiAgfTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihhbGdvLCBrZXkpIHtcbiAgICB2YXIgZGF0YSA9IHRoaXMucGFja2V0cy53cml0ZSgpO1xuXG4gICAgdGhpcy5lbmNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmVuY3J5cHQoXG4gICAgICBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKGFsZ28pLCBhbGdvLCBkYXRhLCBrZXksIHRydWUpO1xuICB9O1xufTtcbiIsIi8qKlxuICogQG1vZHVsZSBwYWNrZXQvdHJ1c3RcbiAqL1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcblxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIFVzZXIgQXR0cmlidXRlIFBhY2tldCAoVGFnIDE3KTxici8+XG4gKiA8YnIvPlxuICogVGhlIFVzZXIgQXR0cmlidXRlIHBhY2tldCBpcyBhIHZhcmlhdGlvbiBvZiB0aGUgVXNlciBJRCBwYWNrZXQuICBJdFxuICogaXMgY2FwYWJsZSBvZiBzdG9yaW5nIG1vcmUgdHlwZXMgb2YgZGF0YSB0aGFuIHRoZSBVc2VyIElEIHBhY2tldCxcbiAqIHdoaWNoIGlzIGxpbWl0ZWQgdG8gdGV4dC4gIExpa2UgdGhlIFVzZXIgSUQgcGFja2V0LCBhIFVzZXIgQXR0cmlidXRlXG4gKiBwYWNrZXQgbWF5IGJlIGNlcnRpZmllZCBieSB0aGUga2V5IG93bmVyIChcInNlbGYtc2lnbmVkXCIpIG9yIGFueSBvdGhlclxuICoga2V5IG93bmVyIHdobyBjYXJlcyB0byBjZXJ0aWZ5IGl0LiAgRXhjZXB0IGFzIG5vdGVkLCBhIFVzZXIgQXR0cmlidXRlXG4gKiBwYWNrZXQgbWF5IGJlIHVzZWQgYW55d2hlcmUgdGhhdCBhIFVzZXIgSUQgcGFja2V0IG1heSBiZSB1c2VkLlxuICogPGJyLz5cbiAqIFdoaWxlIFVzZXIgQXR0cmlidXRlIHBhY2tldHMgYXJlIG5vdCBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIE9wZW5QR1BcbiAqIHN0YW5kYXJkLCBpbXBsZW1lbnRhdGlvbnMgU0hPVUxEIHByb3ZpZGUgYXQgbGVhc3QgZW5vdWdoXG4gKiBjb21wYXRpYmlsaXR5IHRvIHByb3Blcmx5IGhhbmRsZSBhIGNlcnRpZmljYXRpb24gc2lnbmF0dXJlIG9uIHRoZVxuICogVXNlciBBdHRyaWJ1dGUgcGFja2V0LiAgQSBzaW1wbGUgd2F5IHRvIGRvIHRoaXMgaXMgYnkgdHJlYXRpbmcgdGhlXG4gKiBVc2VyIEF0dHJpYnV0ZSBwYWNrZXQgYXMgYSBVc2VyIElEIHBhY2tldCB3aXRoIG9wYXF1ZSBjb250ZW50cywgYnV0XG4gKiBhbiBpbXBsZW1lbnRhdGlvbiBtYXkgdXNlIGFueSBtZXRob2QgZGVzaXJlZC5cbiAqIG1vZHVsZSBwYWNrZXQvdXNlcl9hdHRyaWJ1dGVcbiAqIEBtb2R1bGUgcGFja2V0L3VzZXJfYXR0cmlidXRlXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0LmpzJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnRhZyA9IDE3O1xuICB0aGlzLmF0dHJpYnV0ZXMgPSBbXTtcblxuICAvKipcbiAgICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGF0dHJpYnV0ZSBwYWNrZXQgKHRhZyAxNykuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBwYXlsb2FkIG9mIGEgdGFnIDE3IHBhY2tldFxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHZhciBsZW4gPSBwYWNrZXQucmVhZFNpbXBsZUxlbmd0aChieXRlcy5zdWJzdHIoaSkpO1xuICAgICAgaSArPSBsZW4ub2Zmc2V0O1xuXG4gICAgICB0aGlzLmF0dHJpYnV0ZXMucHVzaChieXRlcy5zdWJzdHIoaSwgbGVuLmxlbikpO1xuICAgICAgaSArPSBsZW4ubGVuO1xuICAgIH1cbiAgfTtcbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBVc2VyIElEIFBhY2tldCAoVGFnIDEzKTxici8+XG4gKiA8YnIvPlxuICogQSBVc2VyIElEIHBhY2tldCBjb25zaXN0cyBvZiBVVEYtOCB0ZXh0IHRoYXQgaXMgaW50ZW5kZWQgdG8gcmVwcmVzZW50XG4gKiB0aGUgbmFtZSBhbmQgZW1haWwgYWRkcmVzcyBvZiB0aGUga2V5IGhvbGRlci4gIEJ5IGNvbnZlbnRpb24sIGl0XG4gKiBpbmNsdWRlcyBhbiBSRkMgMjgyMiBbUkZDMjgyMl0gbWFpbCBuYW1lLWFkZHIsIGJ1dCB0aGVyZSBhcmUgbm9cbiAqIHJlc3RyaWN0aW9ucyBvbiBpdHMgY29udGVudC4gIFRoZSBwYWNrZXQgbGVuZ3RoIGluIHRoZSBoZWFkZXJcbiAqIHNwZWNpZmllcyB0aGUgbGVuZ3RoIG9mIHRoZSBVc2VyIElELlxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgcGFja2V0L3VzZXJpZFxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgLyoqIEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIgaWQuIFVzdWFsbHkgaW4gdGhlIGZvcm1cbiAgICogSm9obiBEb2UgPGpvaG5AZXhhbXBsZS5jb20+XG4gICAqIEB0eXBlIHtTdHJpbmd9IFxuICAgKi9cbiAgdGhpcy51c2VyaWQgPSAnJztcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHVzZXIgaWQgcGFja2V0ICh0YWcgMTMpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxMyBwYWNrZXRcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uIChieXRlcykge1xuICAgIHRoaXMudXNlcmlkID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVzZXIgaWQgcGFja2V0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMudXNlcmlkKTtcbiAgfTtcbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKTxici8+XG4gKiA8YnIvPlxuICogQSBLZXkgSUQgaXMgYW4gZWlnaHQtb2N0ZXQgc2NhbGFyIHRoYXQgaWRlbnRpZmllcyBhIGtleS5cbiAqIEltcGxlbWVudGF0aW9ucyBTSE9VTEQgTk9UIGFzc3VtZSB0aGF0IEtleSBJRHMgYXJlIHVuaXF1ZS4gIFRoZVxuICogc2VjdGlvbiBcIkVuaGFuY2VkIEtleSBGb3JtYXRzXCIgYmVsb3cgZGVzY3JpYmVzIGhvdyBLZXkgSURzIGFyZVxuICogZm9ybWVkLlxuICogQHJlcXVpcmVzIHV0aWxcbiAqIEBtb2R1bGUgdHlwZS9rZXlpZFxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcblxuICB0aGlzLmJ5dGVzID0gJyc7XG5cblxuICAvKipcbiAgICogUGFyc2luZyBtZXRob2QgZm9yIGEga2V5IGlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCB0byByZWFkIHRoZSBrZXkgaWQgZnJvbSBcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdGhpcy5ieXRlcyA9IGJ5dGVzLnN1YnN0cigwLCA4KTtcbiAgfTtcblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXM7XG4gIH07XG5cbiAgdGhpcy50b0hleCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB1dGlsLmhleHN0cmR1bXAodGhpcy5ieXRlcyk7XG4gIH07XG5cbiAgdGhpcy5lcXVhbHMgPSBmdW5jdGlvbihrZXlpZCkge1xuICAgIHJldHVybiB0aGlzLmJ5dGVzID09IGtleWlkLmJ5dGVzO1xuICB9O1xuXG4gIHRoaXMuaXNOdWxsID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXMgPT09ICcnO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMubWFwVG9IZXggPSBmdW5jdGlvbihrZXlJZCkge1xuICByZXR1cm4ga2V5SWQudG9IZXgoKTtcbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8vIEhpbnQ6IFdlIGhvbGQgb3VyIE1QSXMgYXMgYW4gYXJyYXkgb2Ygb2N0ZXRzIGluIGJpZyBlbmRpYW4gZm9ybWF0IHByZWNlZWRpbmcgYSB0d29cbi8vIG9jdGV0IHNjYWxhcjogTVBJOiBbYSxiLGMsZCxlLGZdXG4vLyAtIE1QSSBzaXplOiAoYSA8PCA4KSB8IGIgXG4vLyAtIE1QSSA9IGMgfCBkIDw8IDggfCBlIDw8ICgoTVBJLmxlbmd0aCAtMikqOCkgfCBmICgoTVBJLmxlbmd0aCAtMikqOClcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0eXBlIE1QSSAoUkZDNDg4MCAzLjIpPGJyLz5cbiAqIDxici8+XG4gKiBNdWx0aXByZWNpc2lvbiBpbnRlZ2VycyAoYWxzbyBjYWxsZWQgTVBJcykgYXJlIHVuc2lnbmVkIGludGVnZXJzIHVzZWRcbiAqIHRvIGhvbGQgbGFyZ2UgaW50ZWdlcnMgc3VjaCBhcyB0aGUgb25lcyB1c2VkIGluIGNyeXB0b2dyYXBoaWNcbiAqIGNhbGN1bGF0aW9ucy5cbiAqIEFuIE1QSSBjb25zaXN0cyBvZiB0d28gcGllY2VzOiBhIHR3by1vY3RldCBzY2FsYXIgdGhhdCBpcyB0aGUgbGVuZ3RoXG4gKiBvZiB0aGUgTVBJIGluIGJpdHMgZm9sbG93ZWQgYnkgYSBzdHJpbmcgb2Ygb2N0ZXRzIHRoYXQgY29udGFpbiB0aGVcbiAqIGFjdHVhbCBpbnRlZ2VyLlxuICogQHJlcXVpcmVzIGNyeXB0by9wdWJsaWNfa2V5L2pzYm5cbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIHR5cGUvbXBpXG4gKi9cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuLi9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbXBpKCkge1xuICAvKiogQW4gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50IGludGVnZXIgKi9cbiAgdGhpcy5kYXRhID0gbnVsbDtcblxuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBtcGkgKFJGQyA0ODgwIDMuMikuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIG1waSBkYXRhXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IExlbmd0aCBvZiBkYXRhIHJlYWRcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGJpdHMgPSAoYnl0ZXMuY2hhckNvZGVBdCgwKSA8PCA4KSB8IGJ5dGVzLmNoYXJDb2RlQXQoMSk7XG5cbiAgICAvLyBBZGRpdGlvbmFsIHJ1bGVzOlxuICAgIC8vXG4gICAgLy8gICAgVGhlIHNpemUgb2YgYW4gTVBJIGlzICgoTVBJLmxlbmd0aCArIDcpIC8gOCkgKyAyIG9jdGV0cy5cbiAgICAvL1xuICAgIC8vICAgIFRoZSBsZW5ndGggZmllbGQgb2YgYW4gTVBJIGRlc2NyaWJlcyB0aGUgbGVuZ3RoIHN0YXJ0aW5nIGZyb20gaXRzXG4gICAgLy9cdCAgbW9zdCBzaWduaWZpY2FudCBub24temVybyBiaXQuICBUaHVzLCB0aGUgTVBJIFswMCAwMiAwMV0gaXMgbm90XG4gICAgLy8gICAgZm9ybWVkIGNvcnJlY3RseS4gIEl0IHNob3VsZCBiZSBbMDAgMDEgMDFdLlxuXG4gICAgLy8gVE9ETzogVmVyaWZpY2F0aW9uIG9mIHRoaXMgc2l6ZSBtZXRob2QhIFRoaXMgc2l6ZSBjYWxjdWxhdGlvbiBhc1xuICAgIC8vIFx0XHQgc3BlY2lmaWVkIGFib3ZlIGlzIG5vdCBhcHBsaWNhYmxlIGluIEphdmFTY3JpcHRcbiAgICB2YXIgYnl0ZWxlbiA9IE1hdGguY2VpbChiaXRzIC8gOCk7XG5cbiAgICB2YXIgcmF3ID0gYnl0ZXMuc3Vic3RyKDIsIGJ5dGVsZW4pO1xuICAgIHRoaXMuZnJvbUJ5dGVzKHJhdyk7XG5cbiAgICByZXR1cm4gMiArIGJ5dGVsZW47XG4gIH07XG5cbiAgdGhpcy5mcm9tQnl0ZXMgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHRoaXMuZGF0YSA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChieXRlcyksIDE2KTtcbiAgfTtcblxuICB0aGlzLnRvQnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy53cml0ZSgpLnN1YnN0cigyKTtcbiAgfTtcblxuICB0aGlzLmJ5dGVMZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50b0J5dGVzKCkubGVuZ3RoO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgbXBpIG9iamVjdCB0byBhIHN0cmluZyBhcyBzcGVjaWZpZWQgaW4gUkZDNDg4MCAzLjJcbiAgICogQHJldHVybiB7U3RyaW5nfSBtcGkgQnl0ZSByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEudG9NUEkoKTtcbiAgfTtcblxuICB0aGlzLnRvQmlnSW50ZWdlciA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEuY2xvbmUoKTtcbiAgfTtcblxuICB0aGlzLmZyb21CaWdJbnRlZ2VyID0gZnVuY3Rpb24oYm4pIHtcbiAgICB0aGlzLmRhdGEgPSBibi5jbG9uZSgpO1xuICB9O1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgKFJGQzQ4ODAgMy43KTxici8+XG4gKiA8YnIvPlxuICogU3RyaW5nLXRvLWtleSAoUzJLKSBzcGVjaWZpZXJzIGFyZSB1c2VkIHRvIGNvbnZlcnQgcGFzc3BocmFzZSBzdHJpbmdzXG4gKiBpbnRvIHN5bW1ldHJpYy1rZXkgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGtleXMuICBUaGV5IGFyZSB1c2VkIGluIHR3b1xuICogcGxhY2VzLCBjdXJyZW50bHk6IHRvIGVuY3J5cHQgdGhlIHNlY3JldCBwYXJ0IG9mIHByaXZhdGUga2V5cyBpbiB0aGVcbiAqIHByaXZhdGUga2V5cmluZywgYW5kIHRvIGNvbnZlcnQgcGFzc3BocmFzZXMgdG8gZW5jcnlwdGlvbiBrZXlzIGZvclxuICogc3ltbWV0cmljYWxseSBlbmNyeXB0ZWQgbWVzc2FnZXMuXG4gKiBAcmVxdWlyZXMgY3J5cHRvXG4gKiBAcmVxdWlyZXMgZW51bXNcbiAqIEByZXF1aXJlcyB1dGlsXG4gKiBAbW9kdWxlIHR5cGUvczJrXG4gKi9cblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gczJrKCkge1xuICAvKiogQHR5cGUge21vZHVsZTplbnVtcy5oYXNofSAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICdzaGEyNTYnO1xuICAvKiogQHR5cGUge21vZHVsZTplbnVtcy5zMmt9ICovXG4gIHRoaXMudHlwZSA9ICdpdGVyYXRlZCc7XG4gIHRoaXMuYyA9IDk2O1xuICAvKiogRWlnaHQgYnl0ZXMgb2Ygc2FsdCBpbiBhIGJpbmFyeSBzdHJpbmcuXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICB0aGlzLnNhbHQgPSBjcnlwdG8ucmFuZG9tLmdldFJhbmRvbUJ5dGVzKDgpO1xuXG5cbiAgLy8gRXhwb25lbnQgYmlhcywgZGVmaW5lZCBpbiBSRkM0ODgwXG4gIHZhciBleHBiaWFzID0gNjtcblxuICB0aGlzLmdldF9jb3VudCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAoMTYgKyAodGhpcy5jICYgMTUpKSA8PCAoKHRoaXMuYyA+PiA0KSArIGV4cGJpYXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIChSRkMgNDg4MCAzLjcpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBzdHJpbmctdG8ta2V5IHNwZWNpZmllclxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBY3R1YWwgbGVuZ3RoIG9mIHRoZSBvYmplY3RcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuICAgIHRoaXMudHlwZSA9IGVudW1zLnJlYWQoZW51bXMuczJrLCBieXRlcy5jaGFyQ29kZUF0KGkrKykpO1xuICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5oYXNoLCBieXRlcy5jaGFyQ29kZUF0KGkrKykpO1xuXG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzYWx0ZWQnOlxuICAgICAgICB0aGlzLnNhbHQgPSBieXRlcy5zdWJzdHIoaSwgOCk7XG4gICAgICAgIGkgKz0gODtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgdGhpcy5zYWx0ID0gYnl0ZXMuc3Vic3RyKGksIDgpO1xuICAgICAgICBpICs9IDg7XG5cbiAgICAgICAgLy8gT2N0ZXQgMTA6IGNvdW50LCBhIG9uZS1vY3RldCwgY29kZWQgdmFsdWVcbiAgICAgICAgdGhpcy5jID0gYnl0ZXMuY2hhckNvZGVBdChpKyspO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZ251JzpcbiAgICAgICAgaWYgKGJ5dGVzLnN1YnN0cihpLCAzKSA9PSBcIkdOVVwiKSB7XG4gICAgICAgICAgaSArPSAzOyAvLyBHTlVcbiAgICAgICAgICB2YXIgZ251RXh0VHlwZSA9IDEwMDAgKyBieXRlcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgICAgaWYgKGdudUV4dFR5cGUgPT0gMTAwMSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gZ251RXh0VHlwZTtcbiAgICAgICAgICAgIC8vIEdudVBHIGV4dGVuc2lvbiBtb2RlIDEwMDEgLS0gZG9uJ3Qgd3JpdGUgc2VjcmV0IGtleSBhdCBhbGxcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzMmsgZ251IHByb3RlY3Rpb24gbW9kZS5cIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIHR5cGUuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayB0eXBlLlwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGk7XG4gIH07XG5cblxuICAvKipcbiAgICogd3JpdGVzIGFuIHMyayBoYXNoIGJhc2VkIG9uIHRoZSBpbnB1dHMuXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IG9mIGhhc2hBbGdvcml0aG0gaGFzaCBsZW5ndGhcbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnMyaywgdGhpcy50eXBlKSk7XG4gICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmFsZ29yaXRobSkpO1xuXG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgYnl0ZXMgKz0gdGhpcy5zYWx0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgYnl0ZXMgKz0gdGhpcy5zYWx0O1xuICAgICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuYyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBieXRlcztcbiAgfTtcblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBrZXkgdXNpbmcgdGhlIHNwZWNpZmllZCBwYXNzcGhyYXNlIGFuZCB0aGUgZGVmaW5lZCBcbiAgICogaGFzaEFsZ29yaXRobSBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2UgUGFzc3BocmFzZSBjb250YWluaW5nIHVzZXIgaW5wdXRcbiAgICogQHJldHVybiB7U3RyaW5nfSBQcm9kdWNlZCBrZXkgd2l0aCBhIGxlbmd0aCBjb3JyZXNwb25kaW5nIHRvIFxuICAgKiBoYXNoQWxnb3JpdGhtIGhhc2ggbGVuZ3RoXG4gICAqL1xuICB0aGlzLnByb2R1Y2Vfa2V5ID0gZnVuY3Rpb24ocGFzc3BocmFzZSwgbnVtQnl0ZXMpIHtcbiAgICBwYXNzcGhyYXNlID0gdXRpbC5lbmNvZGVfdXRmOChwYXNzcGhyYXNlKTtcblxuICAgIGZ1bmN0aW9uIHJvdW5kKHByZWZpeCwgczJrKSB7XG4gICAgICB2YXIgYWxnb3JpdGhtID0gZW51bXMud3JpdGUoZW51bXMuaGFzaCwgczJrLmFsZ29yaXRobSk7XG5cbiAgICAgIHN3aXRjaCAoczJrLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2ltcGxlJzpcbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgcGFzc3BocmFzZSk7XG5cbiAgICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSxcbiAgICAgICAgICAgIHByZWZpeCArIHMyay5zYWx0ICsgcGFzc3BocmFzZSk7XG5cbiAgICAgICAgY2FzZSAnaXRlcmF0ZWQnOlxuICAgICAgICAgIHZhciBpc3AgPSBbXSxcbiAgICAgICAgICAgIGNvdW50ID0gczJrLmdldF9jb3VudCgpO1xuICAgICAgICAgIGRhdGEgPSBzMmsuc2FsdCArIHBhc3NwaHJhc2U7XG5cbiAgICAgICAgICB3aGlsZSAoaXNwLmxlbmd0aCAqIGRhdGEubGVuZ3RoIDwgY291bnQpXG4gICAgICAgICAgICBpc3AucHVzaChkYXRhKTtcblxuICAgICAgICAgIGlzcCA9IGlzcC5qb2luKCcnKTtcblxuICAgICAgICAgIGlmIChpc3AubGVuZ3RoID4gY291bnQpXG4gICAgICAgICAgICBpc3AgPSBpc3Auc3Vic3RyKDAsIGNvdW50KTtcblxuICAgICAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5kaWdlc3QoYWxnb3JpdGhtLCBwcmVmaXggKyBpc3ApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciByZXN1bHQgPSAnJyxcbiAgICAgIHByZWZpeCA9ICcnO1xuXG4gICAgd2hpbGUgKHJlc3VsdC5sZW5ndGggPD0gbnVtQnl0ZXMpIHtcbiAgICAgIHJlc3VsdCArPSByb3VuZChwcmVmaXgsIHRoaXMpO1xuICAgICAgcHJlZml4ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdC5zdWJzdHIoMCwgbnVtQnl0ZXMpO1xuICB9O1xufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogVGhpcyBvYmplY3QgY29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnNcbiAqIEByZXF1aXJlcyBjb25maWdcbiAqIEBtb2R1bGUgdXRpbC91dGlsXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmVhZE51bWJlcjogZnVuY3Rpb24gKGJ5dGVzKSB7XG4gICAgdmFyIG4gPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgbiA8PD0gODtcbiAgICAgIG4gKz0gYnl0ZXMuY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbjtcbiAgfSxcblxuICB3cml0ZU51bWJlcjogZnVuY3Rpb24gKG4sIGJ5dGVzKSB7XG4gICAgdmFyIGIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHtcbiAgICAgIGIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobiA+PiAoOCAqIChieXRlcyAtIGkgLSAxKSkpICYgMHhGRik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGI7XG4gIH0sXG5cbiAgcmVhZERhdGU6IGZ1bmN0aW9uIChieXRlcykge1xuICAgIHZhciBuID0gdGhpcy5yZWFkTnVtYmVyKGJ5dGVzKTtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gICAgZC5zZXRUaW1lKG4gKiAxMDAwKTtcbiAgICByZXR1cm4gZDtcbiAgfSxcblxuICB3cml0ZURhdGU6IGZ1bmN0aW9uICh0aW1lKSB7XG4gICAgdmFyIG51bWVyaWMgPSBNYXRoLnJvdW5kKHRpbWUuZ2V0VGltZSgpIC8gMTAwMCk7XG5cbiAgICByZXR1cm4gdGhpcy53cml0ZU51bWJlcihudW1lcmljLCA0KTtcbiAgfSxcblxuICBlbWFpbFJlZ0V4OiAvXlsrYS16QS1aMC05Xy4tXStAKFthLXpBLVowLTktXStcXC4pK1thLXpBLVowLTldezIsNn0kLyxcblxuICBoZXhkdW1wOiBmdW5jdGlvbiAoc3RyKSB7XG4gICAgdmFyIHIgPSBbXTtcbiAgICB2YXIgZSA9IHN0ci5sZW5ndGg7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBoO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoYyA8IGUpIHtcbiAgICAgIGggPSBzdHIuY2hhckNvZGVBdChjKyspLnRvU3RyaW5nKDE2KTtcbiAgICAgIHdoaWxlIChoLmxlbmd0aCA8IDIpIGggPSBcIjBcIiArIGg7XG4gICAgICByLnB1c2goXCIgXCIgKyBoKTtcbiAgICAgIGkrKztcbiAgICAgIGlmIChpICUgMzIgPT0gMClcbiAgICAgICAgci5wdXNoKFwiXFxuICAgICAgICAgICBcIik7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgaGV4c3RyaW5nIGZyb20gYSBiaW5hcnlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBjb250YWluaW5nIHRoZSBoZXhhZGVjaW1hbCB2YWx1ZXNcbiAgICovXG4gIGhleHN0cmR1bXA6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICBpZiAoc3RyID09IG51bGwpXG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyLmNoYXJDb2RlQXQoYysrKS50b1N0cmluZygxNik7XG4gICAgICB3aGlsZSAoaC5sZW5ndGggPCAyKSBoID0gXCIwXCIgKyBoO1xuICAgICAgci5wdXNoKFwiXCIgKyBoKTtcbiAgICB9XG4gICAgcmV0dXJuIHIuam9pbignJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBiaW5hcnkgc3RyaW5nIGZyb20gYSBoZXggZW5jb2RlZCBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBIZXggc3RyaW5nIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgY29udGFpbmluZyB0aGUgYmluYXJ5IHZhbHVlc1xuICAgKi9cbiAgaGV4MmJpbjogZnVuY3Rpb24gKGhleCkge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMilcbiAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGhleC5zdWJzdHIoaSwgMiksIDE2KSk7XG4gICAgcmV0dXJuIHN0cjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRpbmcgYSBoZXggc3RyaW5nIGZyb20gYW4gYmluYXJ5IGFycmF5IG9mIGludGVnZXJzICgwLi4yNTUpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQXJyYXkgb2YgYnl0ZXMgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgaGV4aWR1bXA6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyW2MrK10udG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIlwiICsgaCk7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcgdG8gYSBzdHJpbmcgb2YgdXRmOCBieXRlc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgdmFsaWQgc3F1ZW5jZSBvZiB1dGY4IGJ5dGVzXG4gICAqL1xuICBlbmNvZGVfdXRmODogZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgb2YgdXRmOCBieXRlcyB0byBhIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gdXRmOCBBIHZhbGlkIHNxdWVuY2Ugb2YgdXRmOCBieXRlc1xuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nXG4gICAqL1xuICBkZWNvZGVfdXRmODogZnVuY3Rpb24gKHV0ZjgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUodXRmOCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB1dGY4O1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQ29udmVydCBhbiBhcnJheSBvZiBpbnRlZ2VycygwLjI1NSkgdG8gYSBzdHJpbmdcbiAgICogQHBhcmFtIHtBcnJheTxJbnRlZ2VyPn0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgYmluMnN0cjogZnVuY3Rpb24gKGJpbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJpbltpXSkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gIH0sXG5cbiAgX3N0cjJiaW46IGZ1bmN0aW9uIChzdHIsIHJlc3VsdCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHRbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGFuIGFycmF5IG9mIGludGVnZXJzKDAuMjU1KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge0FycmF5PEludGVnZXI+fSBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2Vyc1xuICAgKi9cbiAgc3RyMmJpbjogZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiB0aGlzLl9zdHIyYmluKHN0ciwgbmV3IEFycmF5KHN0ci5sZW5ndGgpKTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGEgVWludDhBcnJheVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9IFRoZSBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2Vyc1xuICAgKi9cbiAgc3RyMlVpbnQ4QXJyYXk6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RyMmJpbihzdHIsIG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihzdHIubGVuZ3RoKSkpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgVWludDhBcnJheSB0byBhIHN0cmluZy4gVGhpcyBjdXJyZW50bHkgZnVuY3Rpb25zIFxuICAgKiB0aGUgc2FtZSBhcyBiaW4yc3RyLlxuICAgKiBAZnVuY3Rpb24gbW9kdWxlOnV0aWwvdXRpbC5VaW50OEFycmF5MnN0clxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJpbiBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2VycyB0byBjb252ZXJ0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgVWludDhBcnJheTJzdHI6IGZ1bmN0aW9uIChiaW4pIHtcbiAgICByZXR1cm4gdGhpcy5iaW4yc3RyKGJpbik7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgYSAxNmJpdCBzdW0gb2YgYSBzdHJpbmcgYnkgYWRkaW5nIGVhY2ggY2hhcmFjdGVyXG4gICAqIGNvZGVzIG1vZHVsdXMgNjU1MzVcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgU3RyaW5nIHRvIGNyZWF0ZSBhIHN1bSBvZlxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBbiBpbnRlZ2VyIGNvbnRhaW5pbmcgdGhlIHN1bSBvZiBhbGwgY2hhcmFjdGVyXG4gICAqIGNvZGVzICUgNjU1MzVcbiAgICovXG4gIGNhbGNfY2hlY2tzdW06IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdmFyIGNoZWNrc3VtID0ge1xuICAgICAgczogMCxcbiAgICAgIGFkZDogZnVuY3Rpb24gKHNhZGQpIHtcbiAgICAgICAgdGhpcy5zID0gKHRoaXMucyArIHNhZGQpICUgNjU1MzY7XG4gICAgICB9XG4gICAgfTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoZWNrc3VtLmFkZCh0ZXh0LmNoYXJDb2RlQXQoaSkpO1xuICAgIH1cbiAgICByZXR1cm4gY2hlY2tzdW0ucztcbiAgfSxcblxuICAvKipcbiAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgXG4gICAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWZcbiAgICogQGxpbmsgbW9kdWxlOmNvbmZpZy9jb25maWcuZGVidWcgaXMgc2V0IHRvIHRydWUuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBkZWJ1ZyBtZXNzYWdlXG4gICAqL1xuICBwcmludF9kZWJ1ZzogZnVuY3Rpb24gKHN0cikge1xuICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlLiBEZWJ1ZyBcbiAgICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZlxuICAgKiBAbGluayBtb2R1bGU6Y29uZmlnL2NvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS5cbiAgICogRGlmZmVyZW50IHRoYW4gcHJpbnRfZGVidWcgYmVjYXVzZSB3aWxsIGNhbGwgaGV4c3RyZHVtcCBpZmYgbmVjZXNzYXJ5LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyBvZiB0aGUgZGVidWcgbWVzc2FnZVxuICAgKi9cbiAgcHJpbnRfZGVidWdfaGV4c3RyX2R1bXA6IGZ1bmN0aW9uIChzdHIsIHN0clRvSGV4KSB7XG4gICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgc3RyID0gc3RyICsgdGhpcy5oZXhzdHJkdW1wKHN0clRvSGV4KTtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9LFxuXG4gIGdldExlZnROQml0czogZnVuY3Rpb24gKHN0cmluZywgYml0Y291bnQpIHtcbiAgICB2YXIgcmVzdCA9IGJpdGNvdW50ICUgODtcbiAgICBpZiAocmVzdCA9PSAwKVxuICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoMCwgYml0Y291bnQgLyA4KTtcbiAgICB2YXIgYnl0ZXMgPSAoYml0Y291bnQgLSByZXN0KSAvIDggKyAxO1xuICAgIHZhciByZXN1bHQgPSBzdHJpbmcuc3Vic3RyaW5nKDAsIGJ5dGVzKTtcbiAgICByZXR1cm4gdGhpcy5zaGlmdFJpZ2h0KHJlc3VsdCwgOCAtIHJlc3QpOyAvLyArU3RyaW5nLmZyb21DaGFyQ29kZShzdHJpbmcuY2hhckNvZGVBdChieXRlcyAtMSkgPDwgKDgtcmVzdCkgJiAweEZGKTtcbiAgfSxcblxuICAvKipcbiAgICogU2hpZnRpbmcgYSBzdHJpbmcgdG8gbiBiaXRzIHJpZ2h0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHNoaWZ0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0Y291bnQgQW1vdW50IG9mIGJpdHMgdG8gc2hpZnQgKE1VU1QgYmUgc21hbGxlciBcbiAgICogdGhhbiA5KVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJlc3VsdGluZyBzdHJpbmcuIFxuICAgKi9cbiAgc2hpZnRSaWdodDogZnVuY3Rpb24gKHZhbHVlLCBiaXRjb3VudCkge1xuICAgIHZhciB0ZW1wID0gdXRpbC5zdHIyYmluKHZhbHVlKTtcbiAgICBpZiAoYml0Y291bnQgJSA4ICE9IDApIHtcbiAgICAgIGZvciAodmFyIGkgPSB0ZW1wLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRlbXBbaV0gPj49IGJpdGNvdW50ICUgODtcbiAgICAgICAgaWYgKGkgPiAwKVxuICAgICAgICAgIHRlbXBbaV0gfD0gKHRlbXBbaSAtIDFdIDw8ICg4IC0gKGJpdGNvdW50ICUgOCkpKSAmIDB4RkY7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHV0aWwuYmluMnN0cih0ZW1wKTtcbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBhbGdvcml0aG0gdHlwZSBhcyBzdHJpbmdcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBtZXNzYWdlIHR5cGVcbiAgICovXG4gIGdldF9oYXNoQWxnb3JpdGhtU3RyaW5nOiBmdW5jdGlvbiAoYWxnbykge1xuICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gXCJNRDVcIjtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIFwiU0hBMVwiO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gXCJSSVBFTUQxNjBcIjtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgcmV0dXJuIFwiU0hBMjU2XCI7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIHJldHVybiBcIlNIQTM4NFwiO1xuICAgICAgY2FzZSAxMDpcbiAgICAgICAgcmV0dXJuIFwiU0hBNTEyXCI7XG4gICAgICBjYXNlIDExOlxuICAgICAgICByZXR1cm4gXCJTSEEyMjRcIjtcbiAgICB9XG4gICAgcmV0dXJuIFwidW5rbm93blwiO1xuICB9XG59O1xuIl19 ; \ No newline at end of file diff --git a/resources/openpgp.min.js b/resources/openpgp.min.js index 512df734..bf00e610 100644 --- a/resources/openpgp.min.js +++ b/resources/openpgp.min.js @@ -1,6 +1,6 @@ -/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.0.1 - 2013-12-22 */require=function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>=1,0==I&&(I=b(),a=1&I,I=I>>1|128),a}function e(a){for(var b=0,c=a;c--;)b=b<<1|d();return a&&(b=A[b]>>8-a),b}function f(){y=0}function g(a){r++,x[y++]=a,t.push(String.fromCharCode(a)),32768==y&&(y=0)}function h(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function i(){for(;;){if(S[R]>=U)return-1;if(T[S[R]]==R)return S[R]++;S[R]++}}function j(){var a,b=Q[P];if(u&&document.write("
      len:"+R+" treepos:"+P),17==R)return-1;if(P++,R++,a=i(),u&&document.write("
      IsPat "+a),a>=0)b.b0=a,u&&document.write("
      b0 "+b.b0);else if(b.b0=32768,u&&document.write("
      b0 "+b.b0),j())return-1;if(a=i(),a>=0)b.b1=a,u&&document.write("
      b1 "+b.b1),b.jump=null;else if(b.b1=32768,u&&document.write("
      b1 "+b.b1),b.jump=Q[P],b.jumppos=P,j())return-1;return R--,0}function k(a,b,c,d){var e;for(u&&document.write("currentTree "+a+" numval "+b+" lengths "+c+" show "+d),Q=a,P=0,T=c,U=b,e=0;17>e;e++)S[e]=0;if(R=0,j())return u&&alert("invalid huffman tree\n"),-1;if(u){document.write("
      Tree: "+Q.length);for(var f=0;32>f;f++)document.write("Places["+f+"].b0="+Q[f].b0+"
      "),document.write("Places["+f+"].b1="+Q[f].b1+"
      ")}return 0}function l(a){for(var b,c,e,f=0,g=a[f];;)if(e=d(),u&&document.write("b="+e),e){if(!(32768&g.b1))return u&&document.write("ret1"),g.b1;for(g=g.jump,b=a.length,c=0;b>c;c++)if(a[c]===g){f=c;break}}else{if(!(32768&g.b0))return u&&document.write("ret2"),g.b0;f++,g=a[f]}}function m(){var a,i,j,m,n;do{switch(a=d(),j=e(2)){case 0:u&&alert("Stored\n");break;case 1:u&&alert("Fixed Huffman codes\n");break;case 2:u&&alert("Dynamic Huffman codes\n");break;case 3:u&&alert("Reserved block type!!\n");break;default:u&&alert("Unexpected value %d!\n",j)}if(0==j){var o,p;for(c(),o=b(),o|=b()<<8,p=b(),p|=b()<<8,65535&(o^~p)&&document.write("BlockLen checksum mismatch\n");o--;)i=b(),g(i)}else if(1==j)for(var q;;)if(q=A[e(7)]>>1,q>23?(q=q<<1|d(),q>199?(q-=128,q=q<<1|d()):(q-=48,q>143&&(q+=136))):q+=256,256>q)g(q);else{if(256==q)break;var n,r;for(q-=257,n=e(C[q])+B[q],q=A[e(5)]>>3,E[q]>8?(r=e(8),r|=e(E[q]-8)<<8):r=e(E[q]),r+=D[q],q=0;n>q;q++){var i=x[y-r&32767];g(i)}}else if(2==j){var q,s,t,v,w,z=new Array(320);for(t=257+e(5),v=1+e(5),w=4+e(4),q=0;19>q;q++)z[q]=0;for(q=0;w>q;q++)z[F[q]]=e(3);for(n=O.length,m=0;n>m;m++)O[m]=new h;if(k(O,19,z,0))return f(),1;if(u){document.write("
      distanceTree");for(var G=0;G"+O[G].b0+" "+O[G].b1+" "+O[G].jump+" "+O[G].jumppos)}s=t+v,m=0;var H=-1;for(u&&document.write("
      n="+s+" bits: "+J+"
      ");s>m;)if(H++,q=l(O),u&&document.write("
      "+H+" i:"+m+" decode: "+q+" bits "+J+"
      "),16>q)z[m++]=q;else if(16==q){var I;if(q=3+e(2),m+q>s)return f(),1;for(I=m?z[m-1]:0;q--;)z[m++]=I}else{if(q=17==q?3+e(3):11+e(7),m+q>s)return f(),1;for(;q--;)z[m++]=0}for(n=N.length,m=0;n>m;m++)N[m]=new h;if(k(N,t,z,0))return f(),1;for(n=N.length,m=0;n>m;m++)O[m]=new h;var K=new Array;for(m=t;mliteralTree");a:for(;;)if(q=l(N),q>=256){var n,r;if(q-=256,0==q)break;for(q--,n=e(C[q])+B[q],q=l(O),E[q]>8?(r=e(8),r|=e(E[q]-8)<<8):r=e(E[q]),r+=D[q];n--;){if(0>y-r)break a;var i=x[y-r&32767];g(i)}}else g(q)}}while(!a);return f(),c(),0}function n(){u&&alert("NEXTFILE"),t=[];var a=[];if(z=!1,a[0]=b(),a[1]=b(),u&&alert("type: "+a[0]+" "+a[1]),a[0]==parseInt("78",16)&&a[1]==parseInt("da",16)&&(u&&alert("GEONExT-GZIP"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="geonext.gxt",v++),a[0]==parseInt("78",16)&&a[1]==parseInt("9c",16)&&(u&&alert("ZLIB"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="ZLIB",v++),a[0]==parseInt("1f",16)&&a[1]==parseInt("8b",16)&&(u&&alert("GZIP"),o(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="file",v++),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&(z=!0,a[2]=b(),a[3]=b(),a[2]==parseInt("3",16)&&a[3]==parseInt("4",16))){a[0]=b(),a[1]=b(),u&&alert("ZIP-Version: "+a[1]+" "+a[0]/10+"."+a[0]%10),p=b(),p|=b()<<8,u&&alert("gpflags: "+p);var c=b();c|=b()<<8,u&&alert("method: "+c),b(),b(),b(),b();var d=b();d|=b()<<8,d|=b()<<16,d|=b()<<24;var e=b();e|=b()<<8,e|=b()<<16,e|=b()<<24;var f=b();f|=b()<<8,f|=b()<<16,f|=b()<<24,u&&alert("local CRC: "+d+"\nlocal Size: "+f+"\nlocal CompSize: "+e);var g=b();g|=b()<<8;var h=b();for(h|=b()<<8,u&&alert("filelen "+g),j=0,L=[];g--;){var i=b();"/"==i|":"==i?j=0:K-1>j&&(L[j++]=String.fromCharCode(i))}u&&alert("nameBuf: "+L),s||(s=L);for(var j=0;h>j;)i=b(),j++;q=4294967295,r=0,0==f&&"/"==fileOut.charAt(s.length-1)&&u&&alert("skipdir"),8==c&&(m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]=L.join(""),v++),o()}}function o(){var a,c,d,e,f,g,h=[];if(8&p&&(h[0]=b(),h[1]=b(),h[2]=b(),h[3]=b(),h[0]==parseInt("50",16)&&h[1]==parseInt("4b",16)&&h[2]==parseInt("07",16)&&h[3]==parseInt("08",16)?(a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24):a=h[0]|h[1]<<8|h[2]<<16|h[3]<<24,c=b(),c|=b()<<8,c|=b()<<16,c|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,u&&alert("CRC:")),z&&n(),h[0]=b(),8!=h[0])return u&&alert("Unknown compression method!"),0;if(p=b(),u&&p&~parseInt("1f",16)&&alert("Unknown flags set!"),b(),b(),b(),b(),b(),e=b(),4&p)for(h[0]=b(),h[2]=b(),R=h[0]+256*h[1],u&&alert("Extra field size: "+R),f=0;R>f;f++)b();if(8&p){for(f=0,L=[];g=b();)("7"==g||":"==g)&&(f=0),K-1>f&&(L[f++]=g);u&&alert("original file name: "+L)}if(16&p)for(;g=b(););2&p&&(b(),b()),m(),a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,z&&n()}var p,q,r,s,t=[],u=!1,v=0,w=[],x=new Array(32768),y=0,z=!1,A=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],B=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],C=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],D=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],E=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],F=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],G=a,H=0,I=1,J=0,K=256,L=[],M=288,N=new Array(M),O=new Array(32),P=0,Q=null,R=(new Array(64),new Array(64),0),S=new Array(17);S[0]=0;var T,U;JXG.Util.Unzip.prototype.unzipFile=function(a){var b;for(this.unzip(),b=0;b>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i.push([this._keyStr.charAt(e),this._keyStr.charAt(f),this._keyStr.charAt(g),this._keyStr.charAt(h)].join(""));return i.join("")},decode:function(a,b){var c,d,e,f,g,h,i,j=[],k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j.push(String.fromCharCode(c)),64!=h&&j.push(String.fromCharCode(d)),64!=i&&j.push(String.fromCharCode(e));return j=j.join(""),b&&(j=JXG.Util.Base64._utf8_decode(j)),j},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b=[],c=0,d=0,e=0,f=0;cd?(b.push(String.fromCharCode(d)),c++):d>191&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((31&d)<<6|63&e)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((15&d)<<12|(63&e)<<6|63&f)),c+=3);return b.join("")},_destrip:function(a,b){var c,d,e=[],f=[];for(null==b&&(b=76),a.replace(/ /g,""),c=a.length/b,d=0;c>d;d++)e[d]=a.substr(d*b,b);for(c!=a.length/b&&(e[e.length]=a.substr(c*b,a.length-c*b)),d=0;d255)switch(c){case 8364:c=128;break;case 8218:c=130;break;case 402:c=131;break;case 8222:c=132;break;case 8230:c=133;break;case 8224:c=134;break;case 8225:c=135;break;case 710:c=136;break;case 8240:c=137;break;case 352:c=138;break;case 8249:c=139;break;case 338:c=140;break;case 381:c=142;break;case 8216:c=145;break;case 8217:c=146;break;case 8220:c=147;break;case 8221:c=148;break;case 8226:c=149;break;case 8211:c=150;break;case 8212:c=151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c},JXG.Util.utf8Decode=function(a){var b,c=[],d=0,e=0,f=0;if(!JXG.exists(a))return"";for(;de?(c.push(String.fromCharCode(e)),d++):e>191&&224>e?(f=a.charCodeAt(d+1),c.push(String.fromCharCode((31&e)<<6|63&f)),d+=2):(f=a.charCodeAt(d+1),b=a.charCodeAt(d+2),c.push(String.fromCharCode((15&e)<<12|(63&f)<<6|63&b)),d+=3);return c.join("")},JXG.Util.genUUID=function(){for(var a,b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),c=new Array(36),d=0,e=0;36>e;e++)8==e||13==e||18==e||23==e?c[e]="-":14==e?c[e]="4":(2>=d&&(d=33554432+16777216*Math.random()|0),a=15&d,d>>=4,c[e]=b[19==e?3&a|8:a]);return c.join("")},b.exports=JXG},{}],3:[function(a,b){var c=a("../enums.js"),d=function(){this.prefer_hash_algorithm=c.hash.sha256,this.encryption_cipher=c.symmetric.aes256,this.compression=c.compression.zip,this.show_version=!0,this.show_comment=!0,this.integrity_protect=!0,this.keyserver="keyserver.linux.it",this.versionstring="OpenPGP.js v0.0.1.20131222",this.commentstring="http://openpgpjs.org",this.debug=!1};b.exports=new d},{"../enums.js":27}],4:[function(a,b){var c=a("../util"),d=a("./cipher");b.exports={encrypt:function(a,b,e,f,g){b=new d[b](f);var h=b.blockSize,i=new Array(h),j=new Array(h);a=a+a.charAt(h-2)+a.charAt(h-1),c.print_debug("prefixrandom:"+c.hexstrdump(a));for(var k="",l=0;h>l;l++)i[l]=0;j=b.encrypt(i);for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^a.charCodeAt(l));for(var l=0;h>l;l++)i[l]=k.charCodeAt(l);if(j=b.encrypt(i),k+=String.fromCharCode(j[0]^a.charCodeAt(h)),k+=String.fromCharCode(j[1]^a.charCodeAt(h+1)),g)for(var l=0;h>l;l++)i[l]=k.charCodeAt(l+2);else for(var l=0;h>l;l++)i[l]=k.charCodeAt(l);if(j=b.encrypt(i,f),g){for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(l));for(n=h+2;nl;l++)i[l]=k.charCodeAt(n+l);j=b.encrypt(i);for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(n-2+l))}}else{e=" "+e;for(var l=2;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(l));var m=k.substring(0,2*h).split(""),o=k.substring(h);for(n=h;nl;l++)i[l]=o.charCodeAt(l);o="",j=b.encrypt(i);for(var l=0;h>l;l++)m.push(String.fromCharCode(j[l]^e.charCodeAt(n+l))),o+=String.fromCharCode(j[l]^e.charCodeAt(n+l))}k=m.join("")}return k=k.substring(0,e.length+2+h)},mdc:function(a,b,e){a=new d[a](b);var f,g=a.blockSize,h=new Array(g),i=new Array(g);for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=e.charCodeAt(f),h[f]^=i[f];return i=a.encrypt(i),c.bin2str(h)+String.fromCharCode(i[0]^e.charCodeAt(g))+String.fromCharCode(i[1]^e.charCodeAt(g+1))},decrypt:function(a,b,c,e){a=new d[a](b);var f,g=a.blockSize,h=new Array(g),i=new Array(g),j="",k=[];for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h,b),f=0;g>f;f++)i[f]=c.charCodeAt(f),h[f]^=i[f];if(i=a.encrypt(i,b),h[g-2]!=(i[0]^c.charCodeAt(g))||h[g-1]!=(i[1]^c.charCodeAt(g+1)))throw new Error("Invalid data.");if(e){for(f=0;g>f;f++)h[f]=c.charCodeAt(f+2);for(j=g+2;jf&&f+jf;f++)h[f]=c.charCodeAt(f);for(j=g;jf&&f+jg*j;){var m=a.encrypt(c.str2bin(i));h=e.substring(j*g,j*g+g);for(var n=0;nl;l++)h+=String.fromCharCode(0);else h=f.substring(0,g);for(;e.length>g*i;){var m=a.encrypt(c.str2bin(h));h=e.substring(i*g+k,i*g+g+k);for(var l=0;l>8&255}function e(a){return a>>16&255}function f(a){return a>>24&255}function g(a,b,c,e){return d(o[255&a])|d(o[b>>8&255])<<8|d(o[c>>16&255])<<16|d(o[e>>>24])<<24}function h(a){var b,c,d=a.length,e=new Array(d/4);if(a&&!(d%4)){for(b=0,c=0;d>c;c+=4)e[b++]=a[c]|a[c+1]<<8|a[c+2]<<16|a[c+3]<<24;return e}}function i(a){var b,g=0,h=a.length,i=new Array(4*h);for(b=0;h>b;b++)i[g++]=c(a[b]),i[g++]=d(a[b]),i[g++]=e(a[b]),i[g++]=f(a[b]);return i}function j(a){var b,g,h,i,j,k,l=new Array(t+1),o=a.length,p=new Array(s),q=new Array(s),r=0;if(16==o)k=10,b=4;else if(24==o)k=12,b=6;else{if(32!=o)throw new Error("Invalid key-length for AES key:"+o);k=14,b=8}for(g=0;t+1>g;g++)l[g]=new Array(4);for(g=0,h=0;o>h;h++,g+=4)p[h]=a.charCodeAt(g)|a.charCodeAt(g+1)<<8|a.charCodeAt(g+2)<<16|a.charCodeAt(g+3)<<24;for(h=b-1;h>=0;h--)q[h]=p[h];for(i=0,j=0,h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}for(;k+1>i;){var u=q[b-1];if(q[0]^=n[d(u)]|n[e(u)]<<8|n[f(u)]<<16|n[c(u)]<<24,q[0]^=m[r++],8!=b)for(h=1;b>h;h++)q[h]^=q[h-1];else{for(h=1;b/2>h;h++)q[h]^=q[h-1];for(u=q[b/2-1],q[b/2]^=n[c(u)]|n[d(u)]<<8|n[e(u)]<<16|n[f(u)]<<24,h=b/2+1;b>h;h++)q[h]^=q[h-1]}for(h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}}return this.rounds=k,this.rk=l,this}function k(a,b){var c,d,e,f,j,k=h(a),l=b.rounds,m=k[0],n=k[1],s=k[2],t=k[3];for(c=0;l-1>c;c++)d=m^b.rk[c][0],e=n^b.rk[c][1],f=s^b.rk[c][2],j=t^b.rk[c][3],m=o[255&d]^p[e>>8&255]^q[f>>16&255]^r[j>>>24],n=o[255&e]^p[f>>8&255]^q[j>>16&255]^r[d>>>24],s=o[255&f]^p[j>>8&255]^q[d>>16&255]^r[e>>>24],t=o[255&j]^p[d>>8&255]^q[e>>16&255]^r[f>>>24];return c=l-1,d=m^b.rk[c][0],e=n^b.rk[c][1],f=s^b.rk[c][2],j=t^b.rk[c][3],k[0]=g(d,e,f,j)^b.rk[l][0],k[1]=g(e,f,j,d)^b.rk[l][1],k[2]=g(f,j,d,e)^b.rk[l][2],k[3]=g(j,d,e,f)^b.rk[l][3],i(k)}function l(a){var b=function(a){this.key=j(a),this.encrypt=function(a){return k(a,this.key)}};return b.blockSize=b.prototype.blockSize=16,b.keySize=b.prototype.keySize=a/8,b}var m=(a("../../util"),[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145]),n=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],o=[2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996],p=[1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866],q=[1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206],r=[3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246],s=8,t=14;b.exports={};var u=[128,192,256];for(var v in u)b.exports[u[v]]=l(u[v])},{"../../util":56}],6:[function(a,b){function c(){}function d(a){this.bf=new c,this.bf.init(e.str2bin(a)),this.encrypt=function(a){return this.bf.encrypt_block(a)}}c.prototype.BLOCKSIZE=8,c.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],c.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],c.prototype.NN=16,c.prototype._clean=function(a){if(0>a){var b=2147483647&a; +/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.0.1 - 2013-12-26 */require=function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>=1,0==I&&(I=b(),a=1&I,I=I>>1|128),a}function e(a){for(var b=0,c=a;c--;)b=b<<1|d();return a&&(b=A[b]>>8-a),b}function f(){y=0}function g(a){r++,x[y++]=a,t.push(String.fromCharCode(a)),32768==y&&(y=0)}function h(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function i(){for(;;){if(S[R]>=U)return-1;if(T[S[R]]==R)return S[R]++;S[R]++}}function j(){var a,b=Q[P];if(u&&document.write("
      len:"+R+" treepos:"+P),17==R)return-1;if(P++,R++,a=i(),u&&document.write("
      IsPat "+a),a>=0)b.b0=a,u&&document.write("
      b0 "+b.b0);else if(b.b0=32768,u&&document.write("
      b0 "+b.b0),j())return-1;if(a=i(),a>=0)b.b1=a,u&&document.write("
      b1 "+b.b1),b.jump=null;else if(b.b1=32768,u&&document.write("
      b1 "+b.b1),b.jump=Q[P],b.jumppos=P,j())return-1;return R--,0}function k(a,b,c,d){var e;for(u&&document.write("currentTree "+a+" numval "+b+" lengths "+c+" show "+d),Q=a,P=0,T=c,U=b,e=0;17>e;e++)S[e]=0;if(R=0,j())return u&&alert("invalid huffman tree\n"),-1;if(u){document.write("
      Tree: "+Q.length);for(var f=0;32>f;f++)document.write("Places["+f+"].b0="+Q[f].b0+"
      "),document.write("Places["+f+"].b1="+Q[f].b1+"
      ")}return 0}function l(a){for(var b,c,e,f=0,g=a[f];;)if(e=d(),u&&document.write("b="+e),e){if(!(32768&g.b1))return u&&document.write("ret1"),g.b1;for(g=g.jump,b=a.length,c=0;b>c;c++)if(a[c]===g){f=c;break}}else{if(!(32768&g.b0))return u&&document.write("ret2"),g.b0;f++,g=a[f]}}function m(){var a,i,j,m,n;do{switch(a=d(),j=e(2)){case 0:u&&alert("Stored\n");break;case 1:u&&alert("Fixed Huffman codes\n");break;case 2:u&&alert("Dynamic Huffman codes\n");break;case 3:u&&alert("Reserved block type!!\n");break;default:u&&alert("Unexpected value %d!\n",j)}if(0==j){var o,p;for(c(),o=b(),o|=b()<<8,p=b(),p|=b()<<8,65535&(o^~p)&&document.write("BlockLen checksum mismatch\n");o--;)i=b(),g(i)}else if(1==j)for(var q;;)if(q=A[e(7)]>>1,q>23?(q=q<<1|d(),q>199?(q-=128,q=q<<1|d()):(q-=48,q>143&&(q+=136))):q+=256,256>q)g(q);else{if(256==q)break;var n,r;for(q-=257,n=e(C[q])+B[q],q=A[e(5)]>>3,E[q]>8?(r=e(8),r|=e(E[q]-8)<<8):r=e(E[q]),r+=D[q],q=0;n>q;q++){var i=x[y-r&32767];g(i)}}else if(2==j){var q,s,t,v,w,z=new Array(320);for(t=257+e(5),v=1+e(5),w=4+e(4),q=0;19>q;q++)z[q]=0;for(q=0;w>q;q++)z[F[q]]=e(3);for(n=O.length,m=0;n>m;m++)O[m]=new h;if(k(O,19,z,0))return f(),1;if(u){document.write("
      distanceTree");for(var G=0;G"+O[G].b0+" "+O[G].b1+" "+O[G].jump+" "+O[G].jumppos)}s=t+v,m=0;var H=-1;for(u&&document.write("
      n="+s+" bits: "+J+"
      ");s>m;)if(H++,q=l(O),u&&document.write("
      "+H+" i:"+m+" decode: "+q+" bits "+J+"
      "),16>q)z[m++]=q;else if(16==q){var I;if(q=3+e(2),m+q>s)return f(),1;for(I=m?z[m-1]:0;q--;)z[m++]=I}else{if(q=17==q?3+e(3):11+e(7),m+q>s)return f(),1;for(;q--;)z[m++]=0}for(n=N.length,m=0;n>m;m++)N[m]=new h;if(k(N,t,z,0))return f(),1;for(n=N.length,m=0;n>m;m++)O[m]=new h;var K=new Array;for(m=t;mliteralTree");a:for(;;)if(q=l(N),q>=256){var n,r;if(q-=256,0==q)break;for(q--,n=e(C[q])+B[q],q=l(O),E[q]>8?(r=e(8),r|=e(E[q]-8)<<8):r=e(E[q]),r+=D[q];n--;){if(0>y-r)break a;var i=x[y-r&32767];g(i)}}else g(q)}}while(!a);return f(),c(),0}function n(){u&&alert("NEXTFILE"),t=[];var a=[];if(z=!1,a[0]=b(),a[1]=b(),u&&alert("type: "+a[0]+" "+a[1]),a[0]==parseInt("78",16)&&a[1]==parseInt("da",16)&&(u&&alert("GEONExT-GZIP"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="geonext.gxt",v++),a[0]==parseInt("78",16)&&a[1]==parseInt("9c",16)&&(u&&alert("ZLIB"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="ZLIB",v++),a[0]==parseInt("1f",16)&&a[1]==parseInt("8b",16)&&(u&&alert("GZIP"),o(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="file",v++),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&(z=!0,a[2]=b(),a[3]=b(),a[2]==parseInt("3",16)&&a[3]==parseInt("4",16))){a[0]=b(),a[1]=b(),u&&alert("ZIP-Version: "+a[1]+" "+a[0]/10+"."+a[0]%10),p=b(),p|=b()<<8,u&&alert("gpflags: "+p);var c=b();c|=b()<<8,u&&alert("method: "+c),b(),b(),b(),b();var d=b();d|=b()<<8,d|=b()<<16,d|=b()<<24;var e=b();e|=b()<<8,e|=b()<<16,e|=b()<<24;var f=b();f|=b()<<8,f|=b()<<16,f|=b()<<24,u&&alert("local CRC: "+d+"\nlocal Size: "+f+"\nlocal CompSize: "+e);var g=b();g|=b()<<8;var h=b();for(h|=b()<<8,u&&alert("filelen "+g),j=0,L=[];g--;){var i=b();"/"==i|":"==i?j=0:K-1>j&&(L[j++]=String.fromCharCode(i))}u&&alert("nameBuf: "+L),s||(s=L);for(var j=0;h>j;)i=b(),j++;q=4294967295,r=0,0==f&&"/"==fileOut.charAt(s.length-1)&&u&&alert("skipdir"),8==c&&(m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]=L.join(""),v++),o()}}function o(){var a,c,d,e,f,g,h=[];if(8&p&&(h[0]=b(),h[1]=b(),h[2]=b(),h[3]=b(),h[0]==parseInt("50",16)&&h[1]==parseInt("4b",16)&&h[2]==parseInt("07",16)&&h[3]==parseInt("08",16)?(a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24):a=h[0]|h[1]<<8|h[2]<<16|h[3]<<24,c=b(),c|=b()<<8,c|=b()<<16,c|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,u&&alert("CRC:")),z&&n(),h[0]=b(),8!=h[0])return u&&alert("Unknown compression method!"),0;if(p=b(),u&&p&~parseInt("1f",16)&&alert("Unknown flags set!"),b(),b(),b(),b(),b(),e=b(),4&p)for(h[0]=b(),h[2]=b(),R=h[0]+256*h[1],u&&alert("Extra field size: "+R),f=0;R>f;f++)b();if(8&p){for(f=0,L=[];g=b();)("7"==g||":"==g)&&(f=0),K-1>f&&(L[f++]=g);u&&alert("original file name: "+L)}if(16&p)for(;g=b(););2&p&&(b(),b()),m(),a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,z&&n()}var p,q,r,s,t=[],u=!1,v=0,w=[],x=new Array(32768),y=0,z=!1,A=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],B=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],C=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],D=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],E=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],F=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],G=a,H=0,I=1,J=0,K=256,L=[],M=288,N=new Array(M),O=new Array(32),P=0,Q=null,R=(new Array(64),new Array(64),0),S=new Array(17);S[0]=0;var T,U;JXG.Util.Unzip.prototype.unzipFile=function(a){var b;for(this.unzip(),b=0;b>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i.push([this._keyStr.charAt(e),this._keyStr.charAt(f),this._keyStr.charAt(g),this._keyStr.charAt(h)].join(""));return i.join("")},decode:function(a,b){var c,d,e,f,g,h,i,j=[],k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j.push(String.fromCharCode(c)),64!=h&&j.push(String.fromCharCode(d)),64!=i&&j.push(String.fromCharCode(e));return j=j.join(""),b&&(j=JXG.Util.Base64._utf8_decode(j)),j},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b=[],c=0,d=0,e=0,f=0;cd?(b.push(String.fromCharCode(d)),c++):d>191&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((31&d)<<6|63&e)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((15&d)<<12|(63&e)<<6|63&f)),c+=3);return b.join("")},_destrip:function(a,b){var c,d,e=[],f=[];for(null==b&&(b=76),a.replace(/ /g,""),c=a.length/b,d=0;c>d;d++)e[d]=a.substr(d*b,b);for(c!=a.length/b&&(e[e.length]=a.substr(c*b,a.length-c*b)),d=0;d255)switch(c){case 8364:c=128;break;case 8218:c=130;break;case 402:c=131;break;case 8222:c=132;break;case 8230:c=133;break;case 8224:c=134;break;case 8225:c=135;break;case 710:c=136;break;case 8240:c=137;break;case 352:c=138;break;case 8249:c=139;break;case 338:c=140;break;case 381:c=142;break;case 8216:c=145;break;case 8217:c=146;break;case 8220:c=147;break;case 8221:c=148;break;case 8226:c=149;break;case 8211:c=150;break;case 8212:c=151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c},JXG.Util.utf8Decode=function(a){var b,c=[],d=0,e=0,f=0;if(!JXG.exists(a))return"";for(;de?(c.push(String.fromCharCode(e)),d++):e>191&&224>e?(f=a.charCodeAt(d+1),c.push(String.fromCharCode((31&e)<<6|63&f)),d+=2):(f=a.charCodeAt(d+1),b=a.charCodeAt(d+2),c.push(String.fromCharCode((15&e)<<12|(63&f)<<6|63&b)),d+=3);return c.join("")},JXG.Util.genUUID=function(){for(var a,b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),c=new Array(36),d=0,e=0;36>e;e++)8==e||13==e||18==e||23==e?c[e]="-":14==e?c[e]="4":(2>=d&&(d=33554432+16777216*Math.random()|0),a=15&d,d>>=4,c[e]=b[19==e?3&a|8:a]);return c.join("")},b.exports=JXG},{}],3:[function(a,b){var c=a("../enums.js");b.exports={prefer_hash_algorithm:c.hash.sha256,encryption_cipher:c.symmetric.aes256,compression:c.compression.zip,show_version:!0,show_comment:!0,integrity_protect:!0,keyserver:"keyserver.linux.it",versionstring:"OpenPGP.js v0.0.1.20131226",commentstring:"http://openpgpjs.org",debug:!1}},{"../enums.js":27}],4:[function(a,b){var c=a("../util"),d=a("./cipher");b.exports={encrypt:function(a,b,e,f,g){b=new d[b](f);var h=b.blockSize,i=new Array(h),j=new Array(h);a=a+a.charAt(h-2)+a.charAt(h-1),c.print_debug("prefixrandom:"+c.hexstrdump(a));for(var k="",l=0;h>l;l++)i[l]=0;j=b.encrypt(i);for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^a.charCodeAt(l));for(var l=0;h>l;l++)i[l]=k.charCodeAt(l);if(j=b.encrypt(i),k+=String.fromCharCode(j[0]^a.charCodeAt(h)),k+=String.fromCharCode(j[1]^a.charCodeAt(h+1)),g)for(var l=0;h>l;l++)i[l]=k.charCodeAt(l+2);else for(var l=0;h>l;l++)i[l]=k.charCodeAt(l);if(j=b.encrypt(i,f),g){for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(l));for(n=h+2;nl;l++)i[l]=k.charCodeAt(n+l);j=b.encrypt(i);for(var l=0;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(n-2+l))}}else{e=" "+e;for(var l=2;h>l;l++)k+=String.fromCharCode(j[l]^e.charCodeAt(l));var m=k.substring(0,2*h).split(""),o=k.substring(h);for(n=h;nl;l++)i[l]=o.charCodeAt(l);o="",j=b.encrypt(i);for(var l=0;h>l;l++)m.push(String.fromCharCode(j[l]^e.charCodeAt(n+l))),o+=String.fromCharCode(j[l]^e.charCodeAt(n+l))}k=m.join("")}return k=k.substring(0,e.length+2+h)},mdc:function(a,b,e){a=new d[a](b);var f,g=a.blockSize,h=new Array(g),i=new Array(g);for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=e.charCodeAt(f),h[f]^=i[f];return i=a.encrypt(i),c.bin2str(h)+String.fromCharCode(i[0]^e.charCodeAt(g))+String.fromCharCode(i[1]^e.charCodeAt(g+1))},decrypt:function(a,b,c,e){a=new d[a](b);var f,g=a.blockSize,h=new Array(g),i=new Array(g),j="",k=[];for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h,b),f=0;g>f;f++)i[f]=c.charCodeAt(f),h[f]^=i[f];if(i=a.encrypt(i,b),h[g-2]!=(i[0]^c.charCodeAt(g))||h[g-1]!=(i[1]^c.charCodeAt(g+1)))throw new Error("Invalid data.");if(e){for(f=0;g>f;f++)h[f]=c.charCodeAt(f+2);for(j=g+2;jf&&f+jf;f++)h[f]=c.charCodeAt(f);for(j=g;jf&&f+jg*j;){var m=a.encrypt(c.str2bin(i));h=e.substring(j*g,j*g+g);for(var n=0;nl;l++)h+=String.fromCharCode(0);else h=f.substring(0,g);for(;e.length>g*i;){var m=a.encrypt(c.str2bin(h));h=e.substring(i*g+k,i*g+g+k);for(var l=0;l>8&255}function e(a){return a>>16&255}function f(a){return a>>24&255}function g(a,b,c,e){return d(o[255&a])|d(o[b>>8&255])<<8|d(o[c>>16&255])<<16|d(o[e>>>24])<<24}function h(a){var b,c,d=a.length,e=new Array(d/4);if(a&&!(d%4)){for(b=0,c=0;d>c;c+=4)e[b++]=a[c]|a[c+1]<<8|a[c+2]<<16|a[c+3]<<24;return e}}function i(a){var b,g=0,h=a.length,i=new Array(4*h);for(b=0;h>b;b++)i[g++]=c(a[b]),i[g++]=d(a[b]),i[g++]=e(a[b]),i[g++]=f(a[b]);return i}function j(a){var b,g,h,i,j,k,l=new Array(t+1),o=a.length,p=new Array(s),q=new Array(s),r=0;if(16==o)k=10,b=4;else if(24==o)k=12,b=6;else{if(32!=o)throw new Error("Invalid key-length for AES key:"+o);k=14,b=8}for(g=0;t+1>g;g++)l[g]=new Array(4);for(g=0,h=0;o>h;h++,g+=4)p[h]=a.charCodeAt(g)|a.charCodeAt(g+1)<<8|a.charCodeAt(g+2)<<16|a.charCodeAt(g+3)<<24;for(h=b-1;h>=0;h--)q[h]=p[h];for(i=0,j=0,h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}for(;k+1>i;){var u=q[b-1];if(q[0]^=n[d(u)]|n[e(u)]<<8|n[f(u)]<<16|n[c(u)]<<24,q[0]^=m[r++],8!=b)for(h=1;b>h;h++)q[h]^=q[h-1];else{for(h=1;b/2>h;h++)q[h]^=q[h-1];for(u=q[b/2-1],q[b/2]^=n[c(u)]|n[d(u)]<<8|n[e(u)]<<16|n[f(u)]<<24,h=b/2+1;b>h;h++)q[h]^=q[h-1]}for(h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}}return this.rounds=k,this.rk=l,this}function k(a,b){var c,d,e,f,j,k=h(a),l=b.rounds,m=k[0],n=k[1],s=k[2],t=k[3];for(c=0;l-1>c;c++)d=m^b.rk[c][0],e=n^b.rk[c][1],f=s^b.rk[c][2],j=t^b.rk[c][3],m=o[255&d]^p[e>>8&255]^q[f>>16&255]^r[j>>>24],n=o[255&e]^p[f>>8&255]^q[j>>16&255]^r[d>>>24],s=o[255&f]^p[j>>8&255]^q[d>>16&255]^r[e>>>24],t=o[255&j]^p[d>>8&255]^q[e>>16&255]^r[f>>>24];return c=l-1,d=m^b.rk[c][0],e=n^b.rk[c][1],f=s^b.rk[c][2],j=t^b.rk[c][3],k[0]=g(d,e,f,j)^b.rk[l][0],k[1]=g(e,f,j,d)^b.rk[l][1],k[2]=g(f,j,d,e)^b.rk[l][2],k[3]=g(j,d,e,f)^b.rk[l][3],i(k)}function l(a){var b=function(a){this.key=j(a),this.encrypt=function(a){return k(a,this.key)}};return b.blockSize=b.prototype.blockSize=16,b.keySize=b.prototype.keySize=a/8,b}var m=(a("../../util"),[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145]),n=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],o=[2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996],p=[1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866],q=[1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206],r=[3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246],s=8,t=14;b.exports={};var u=[128,192,256];for(var v in u)b.exports[u[v]]=l(u[v])},{"../../util":56}],6:[function(a,b){function c(){}function d(a){this.bf=new c,this.bf.init(e.str2bin(a)),this.encrypt=function(a){return this.bf.encrypt_block(a)}}c.prototype.BLOCKSIZE=8,c.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],c.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],c.prototype.NN=16,c.prototype._clean=function(a){if(0>a){var b=2147483647&a; a=b+2147483648}return a},c.prototype._F=function(a){var b,c,d,e,f;return e=255&a,a>>>=8,d=255&a,a>>>=8,c=255&a,a>>>=8,b=255&a,f=this.sboxes[0][b]+this.sboxes[1][c],f^=this.sboxes[2][d],f+=this.sboxes[3][e]},c.prototype._encrypt_block=function(a){var b,c=a[0],d=a[1];for(b=0;b>>24-8*b&255,e[b+d]=c[1]>>>24-8*b&255;return e},c.prototype._decrypt_block=function(a){var b,c=a[0],d=a[1];for(b=this.NN+1;b>1;--b){c^=this.parray[b],d=this._F(c)^d;var e=c;c=d,d=e}c^=this.parray[1],d^=this.parray[0],a[0]=this._clean(d),a[1]=this._clean(c)},c.prototype.init=function(a){var b,c=0;for(this.parray=[],b=0;bd;++d)e=e<<8|255&a[c],++c>=a.length&&(c=0);this.parray[b]=this.PARRAY[b]^e}for(this.sboxes=[],b=0;4>b;++b)for(this.sboxes[b]=[],c=0;256>c;++c)this.sboxes[b][c]=this.SBOXES[b][c];var f=[0,0];for(b=0;bb;++b)for(c=0;256>c;c+=2)this._encrypt_block(f),this.sboxes[b][c+0]=f[0],this.sboxes[b][c+1]=f[1]};var e=a("../../util");b.exports=d,b.exports.keySize=d.prototype.keySize=16,b.exports.blockSize=d.prototype.blockSize=16},{"../../util":56}],7:[function(a,b){function c(){function a(a,b,c){var d=b+a,e=d<>>32-c;return(f[0][e>>>24]^f[1][e>>>16&255])-f[2][e>>>8&255]+f[3][255&e]}function b(a,b,c){var d=b^a,e=d<>>32-c;return f[0][e>>>24]-f[1][e>>>16&255]+f[2][e>>>8&255]^f[3][255&e]}function c(a,b,c){var d=b-a,e=d<>>32-c;return(f[0][e>>>24]+f[1][e>>>16&255]^f[2][e>>>8&255])-f[3][255&e]}this.BlockSize=8,this.KeySize=16,this.setKey=function(a){if(this.masking=new Array(16),this.rotate=new Array(16),this.reset(),a.length!=this.KeySize)throw new Error("CAST-128: keys must be 16 bytes");return this.keySchedule(a),!0},this.reset=function(){for(var a=0;16>a;a++)this.masking[a]=0,this.rotate[a]=0},this.getBlockSize=function(){return BlockSize},this.encrypt=function(d){for(var e=new Array(d.length),f=0;f>>24&255,e[f+1]=i>>>16&255,e[f+2]=i>>>8&255,e[f+3]=255&i,e[f+4]=h>>>24&255,e[f+5]=h>>>16&255,e[f+6]=h>>>8&255,e[f+7]=255&h}return e},this.decrypt=function(d){for(var e=new Array(d.length),f=0;f>>24&255,e[f+1]=i>>>16&255,e[f+2]=i>>>8&255,e[f+3]=255&i,e[f+4]=h>>>24&255,e[f+5]=h>>16&255,e[f+6]=h>>8&255,e[f+7]=255&h}return e};var d=new Array(4);d[0]=new Array(4),d[0][0]=new Array(4,0,13,15,12,14,8),d[0][1]=new Array(5,2,16,18,17,19,10),d[0][2]=new Array(6,3,23,22,21,20,9),d[0][3]=new Array(7,1,26,25,27,24,11),d[1]=new Array(4),d[1][0]=new Array(0,6,21,23,20,22,16),d[1][1]=new Array(1,4,0,2,1,3,18),d[1][2]=new Array(2,5,7,6,5,4,17),d[1][3]=new Array(3,7,10,9,11,8,19),d[2]=new Array(4),d[2][0]=new Array(4,0,13,15,12,14,8),d[2][1]=new Array(5,2,16,18,17,19,10),d[2][2]=new Array(6,3,23,22,21,20,9),d[2][3]=new Array(7,1,26,25,27,24,11),d[3]=new Array(4),d[3][0]=new Array(0,6,21,23,20,22,16),d[3][1]=new Array(1,4,0,2,1,3,18),d[3][2]=new Array(2,5,7,6,5,4,17),d[3][3]=new Array(3,7,10,9,11,8,19);var e=new Array(4);e[0]=new Array(4),e[0][0]=new Array(24,25,23,22,18),e[0][1]=new Array(26,27,21,20,22),e[0][2]=new Array(28,29,19,18,25),e[0][3]=new Array(30,31,17,16,28),e[1]=new Array(4),e[1][0]=new Array(3,2,12,13,8),e[1][1]=new Array(1,0,14,15,13),e[1][2]=new Array(7,6,8,9,3),e[1][3]=new Array(5,4,10,11,7),e[2]=new Array(4),e[2][0]=new Array(19,18,28,29,25),e[2][1]=new Array(17,16,30,31,28),e[2][2]=new Array(23,22,24,25,18),e[2][3]=new Array(21,20,26,27,22),e[3]=new Array(4),e[3][0]=new Array(8,9,7,6,3),e[3][1]=new Array(10,11,5,4,7),e[3][2]=new Array(12,13,3,2,8),e[3][3]=new Array(14,15,1,0,13),this.keySchedule=function(a){for(var b=new Array(8),c=new Array(32),g=0;4>g;g++){var h=4*g;b[g]=a[h]<<24|a[h+1]<<16|a[h+2]<<8|a[h+3]}for(var i=[6,7,4,5],j=0,k=0;2>k;k++)for(var l=0;4>l;l++){for(var h=0;4>h;h++){var m=d[l][h],n=b[m[1]];n^=f[4][b[m[2]>>>2]>>>24-8*(3&m[2])&255],n^=f[5][b[m[3]>>>2]>>>24-8*(3&m[3])&255],n^=f[6][b[m[4]>>>2]>>>24-8*(3&m[4])&255],n^=f[7][b[m[5]>>>2]>>>24-8*(3&m[5])&255],n^=f[i[h]][b[m[6]>>>2]>>>24-8*(3&m[6])&255],b[m[0]]=n}for(var h=0;4>h;h++){var o=e[l][h],n=f[4][b[o[0]>>>2]>>>24-8*(3&o[0])&255];n^=f[5][b[o[1]>>>2]>>>24-8*(3&o[1])&255],n^=f[6][b[o[2]>>>2]>>>24-8*(3&o[2])&255],n^=f[7][b[o[3]>>>2]>>>24-8*(3&o[3])&255],n^=f[4+h][b[o[4]>>>2]>>>24-8*(3&o[4])&255],c[j]=n,j++}}for(var g=0;16>g;g++)this.masking[g]=c[g],this.rotate[g]=31&c[16+g]};var f=new Array(8);f[0]=new Array(821772500,2678128395,1810681135,1059425402,505495343,2617265619,1610868032,3483355465,3218386727,2294005173,3791863952,2563806837,1852023008,365126098,3269944861,584384398,677919599,3229601881,4280515016,2002735330,1136869587,3744433750,2289869850,2731719981,2714362070,879511577,1639411079,575934255,717107937,2857637483,576097850,2731753936,1725645e3,2810460463,5111599,767152862,2543075244,1251459544,1383482551,3052681127,3089939183,3612463449,1878520045,1510570527,2189125840,2431448366,582008916,3163445557,1265446783,1354458274,3529918736,3202711853,3073581712,3912963487,3029263377,1275016285,4249207360,2905708351,3304509486,1442611557,3585198765,2712415662,2731849581,3248163920,2283946226,208555832,2766454743,1331405426,1447828783,3315356441,3108627284,2957404670,2981538698,3339933917,1669711173,286233437,1465092821,1782121619,3862771680,710211251,980974943,1651941557,430374111,2051154026,704238805,4128970897,3144820574,2857402727,948965521,3333752299,2227686284,718756367,2269778983,2731643755,718440111,2857816721,3616097120,1113355533,2478022182,410092745,1811985197,1944238868,2696854588,1415722873,1682284203,1060277122,1998114690,1503841958,82706478,2315155686,1068173648,845149890,2167947013,1768146376,1993038550,3566826697,3390574031,940016341,3355073782,2328040721,904371731,1205506512,4094660742,2816623006,825647681,85914773,2857843460,1249926541,1417871568,3287612,3211054559,3126306446,1975924523,1353700161,2814456437,2438597621,1800716203,722146342,2873936343,1151126914,4160483941,2877670899,458611604,2866078500,3483680063,770352098,2652916994,3367839148,3940505011,3585973912,3809620402,718646636,2504206814,2914927912,3631288169,2857486607,2860018678,575749918,2857478043,718488780,2069512688,3548183469,453416197,1106044049,3032691430,52586708,3378514636,3459808877,3211506028,1785789304,218356169,3571399134,3759170522,1194783844,1523787992,3007827094,1975193539,2555452411,1341901877,3045838698,3776907964,3217423946,2802510864,2889438986,1057244207,1636348243,3761863214,1462225785,2632663439,481089165,718503062,24497053,3332243209,3344655856,3655024856,3960371065,1195698900,2971415156,3710176158,2115785917,4027663609,3525578417,2524296189,2745972565,3564906415,1372086093,1452307862,2780501478,1476592880,3389271281,18495466,2378148571,901398090,891748256,3279637769,3157290713,2560960102,1447622437,4284372637,216884176,2086908623,1879786977,3588903153,2242455666,2938092967,3559082096,2810645491,758861177,1121993112,215018983,642190776,4169236812,1196255959,2081185372,3508738393,941322904,4124243163,2877523539,1848581667,2205260958,3180453958,2589345134,3694731276,550028657,2519456284,3789985535,2973870856,2093648313,443148163,46942275,2734146937,1117713533,1115362972,1523183689,3717140224,1551984063),f[1]=new Array(522195092,4010518363,1776537470,960447360,4267822970,4005896314,1435016340,1929119313,2913464185,1310552629,3579470798,3724818106,2579771631,1594623892,417127293,2715217907,2696228731,1508390405,3994398868,3925858569,3695444102,4019471449,3129199795,3770928635,3520741761,990456497,4187484609,2783367035,21106139,3840405339,631373633,3783325702,532942976,396095098,3548038825,4267192484,2564721535,2011709262,2039648873,620404603,3776170075,2898526339,3612357925,4159332703,1645490516,223693667,1567101217,3362177881,1029951347,3470931136,3570957959,1550265121,119497089,972513919,907948164,3840628539,1613718692,3594177948,465323573,2659255085,654439692,2575596212,2699288441,3127702412,277098644,624404830,4100943870,2717858591,546110314,2403699828,3655377447,1321679412,4236791657,1045293279,4010672264,895050893,2319792268,494945126,1914543101,2777056443,3894764339,2219737618,311263384,4275257268,3458730721,669096869,3584475730,3835122877,3319158237,3949359204,2005142349,2713102337,2228954793,3769984788,569394103,3855636576,1425027204,108000370,2736431443,3671869269,3043122623,1750473702,2211081108,762237499,3972989403,2798899386,3061857628,2943854345,867476300,964413654,1591880597,1594774276,2179821409,552026980,3026064248,3726140315,2283577634,3110545105,2152310760,582474363,1582640421,1383256631,2043843868,3322775884,1217180674,463797851,2763038571,480777679,2718707717,2289164131,3118346187,214354409,200212307,3810608407,3025414197,2674075964,3997296425,1847405948,1342460550,510035443,4080271814,815934613,833030224,1620250387,1945732119,2703661145,3966000196,1388869545,3456054182,2687178561,2092620194,562037615,1356438536,3409922145,3261847397,1688467115,2150901366,631725691,3840332284,549916902,3455104640,394546491,837744717,2114462948,751520235,2221554606,2415360136,3999097078,2063029875,803036379,2702586305,821456707,3019566164,360699898,4018502092,3511869016,3677355358,2402471449,812317050,49299192,2570164949,3259169295,2816732080,3331213574,3101303564,2156015656,3705598920,3546263921,143268808,3200304480,1638124008,3165189453,3341807610,578956953,2193977524,3638120073,2333881532,807278310,658237817,2969561766,1641658566,11683945,3086995007,148645947,1138423386,4158756760,1981396783,2401016740,3699783584,380097457,2680394679,2803068651,3334260286,441530178,4016580796,1375954390,761952171,891809099,2183123478,157052462,3683840763,1592404427,341349109,2438483839,1417898363,644327628,2233032776,2353769706,2201510100,220455161,1815641738,182899273,2995019788,3627381533,3702638151,2890684138,1052606899,588164016,1681439879,4038439418,2405343923,4229449282,167996282,1336969661,1688053129,2739224926,1543734051,1046297529,1138201970,2121126012,115334942,1819067631,1902159161,1941945968,2206692869,1159982321),f[2]=new Array(2381300288,637164959,3952098751,3893414151,1197506559,916448331,2350892612,2932787856,3199334847,4009478890,3905886544,1373570990,2450425862,4037870920,3778841987,2456817877,286293407,124026297,3001279700,1028597854,3115296800,4208886496,2691114635,2188540206,1430237888,1218109995,3572471700,308166588,570424558,2187009021,2455094765,307733056,1310360322,3135275007,1384269543,2388071438,863238079,2359263624,2801553128,3380786597,2831162807,1470087780,1728663345,4072488799,1090516929,532123132,2389430977,1132193179,2578464191,3051079243,1670234342,1434557849,2711078940,1241591150,3314043432,3435360113,3091448339,1812415473,2198440252,267246943,796911696,3619716990,38830015,1526438404,2806502096,374413614,2943401790,1489179520,1603809326,1920779204,168801282,260042626,2358705581,1563175598,2397674057,1356499128,2217211040,514611088,2037363785,2186468373,4022173083,2792511869,2913485016,1173701892,4200428547,3896427269,1334932762,2455136706,602925377,2835607854,1613172210,41346230,2499634548,2457437618,2188827595,41386358,4172255629,1313404830,2405527007,3801973774,2217704835,873260488,2528884354,2478092616,4012915883,2555359016,2006953883,2463913485,575479328,2218240648,2099895446,660001756,2341502190,3038761536,3888151779,3848713377,3286851934,1022894237,1620365795,3449594689,1551255054,15374395,3570825345,4249311020,4151111129,3181912732,310226346,1133119310,530038928,136043402,2476768958,3107506709,2544909567,1036173560,2367337196,1681395281,1758231547,3641649032,306774401,1575354324,3716085866,1990386196,3114533736,2455606671,1262092282,3124342505,2768229131,4210529083,1833535011,423410938,660763973,2187129978,1639812e3,3508421329,3467445492,310289298,272797111,2188552562,2456863912,310240523,677093832,1013118031,901835429,3892695601,1116285435,3036471170,1337354835,243122523,520626091,277223598,4244441197,4194248841,1766575121,594173102,316590669,742362309,3536858622,4176435350,3838792410,2501204839,1229605004,3115755532,1552908988,2312334149,979407927,3959474601,1148277331,176638793,3614686272,2083809052,40992502,1340822838,2731552767,3535757508,3560899520,1354035053,122129617,7215240,2732932949,3118912700,2718203926,2539075635,3609230695,3725561661,1928887091,2882293555,1988674909,2063640240,2491088897,1459647954,4189817080,2302804382,1113892351,2237858528,1927010603,4002880361,1856122846,1594404395,2944033133,3855189863,3474975698,1643104450,4054590833,3431086530,1730235576,2984608721,3084664418,2131803598,4178205752,267404349,1617849798,1616132681,1462223176,736725533,2327058232,551665188,2945899023,1749386277,2575514597,1611482493,674206544,2201269090,3642560800,728599968,1680547377,2620414464,1388111496,453204106,4156223445,1094905244,2754698257,2201108165,3757000246,2704524545,3922940700,3996465027),f[3]=new Array(2645754912,532081118,2814278639,3530793624,1246723035,1689095255,2236679235,4194438865,2116582143,3859789411,157234593,2045505824,4245003587,1687664561,4083425123,605965023,672431967,1336064205,3376611392,214114848,4258466608,3232053071,489488601,605322005,3998028058,264917351,1912574028,756637694,436560991,202637054,135989450,85393697,2152923392,3896401662,2895836408,2145855233,3535335007,115294817,3147733898,1922296357,3464822751,4117858305,1037454084,2725193275,2127856640,1417604070,1148013728,1827919605,642362335,2929772533,909348033,1346338451,3547799649,297154785,1917849091,4161712827,2883604526,3968694238,1469521537,3780077382,3375584256,1763717519,136166297,4290970789,1295325189,2134727907,2798151366,1566297257,3672928234,2677174161,2672173615,965822077,2780786062,289653839,1133871874,3491843819,35685304,1068898316,418943774,672553190,642281022,2346158704,1954014401,3037126780,4079815205,2030668546,3840588673,672283427,1776201016,359975446,3750173538,555499703,2769985273,1324923,69110472,152125443,3176785106,3822147285,1340634837,798073664,1434183902,15393959,216384236,1303690150,3881221631,3711134124,3960975413,106373927,2578434224,1455997841,1801814300,1578393881,1854262133,3188178946,3258078583,2302670060,1539295533,3505142565,3078625975,2372746020,549938159,3278284284,2620926080,181285381,2865321098,3970029511,68876850,488006234,1728155692,2608167508,836007927,2435231793,919367643,3339422534,3655756360,1457871481,40520939,1380155135,797931188,234455205,2255801827,3990488299,397000196,739833055,3077865373,2871719860,4022553888,772369276,390177364,3853951029,557662966,740064294,1640166671,1699928825,3535942136,622006121,3625353122,68743880,1742502,219489963,1664179233,1577743084,1236991741,410585305,2366487942,823226535,1050371084,3426619607,3586839478,212779912,4147118561,1819446015,1911218849,530248558,3486241071,3252585495,2886188651,3410272728,2342195030,20547779,2982490058,3032363469,3631753222,312714466,1870521650,1493008054,3491686656,615382978,4103671749,2534517445,1932181,2196105170,278426614,6369430,3274544417,2913018367,697336853,2143000447,2946413531,701099306,1558357093,2805003052,3500818408,2321334417,3567135975,216290473,3591032198,23009561,1996984579,3735042806,2024298078,3739440863,569400510,2339758983,3016033873,3097871343,3639523026,3844324983,3256173865,795471839,2951117563,4101031090,4091603803,3603732598,971261452,534414648,428311343,3389027175,2844869880,694888862,1227866773,2456207019,3043454569,2614353370,3749578031,3676663836,459166190,4132644070,1794958188,51825668,2252611902,3084671440,2036672799,3436641603,1099053433,2469121526,3059204941,1323291266,2061838604,1018778475,2233344254,2553501054,334295216,3556750194,1065731521,183467730),f[4]=new Array(2127105028,745436345,2601412319,2788391185,3093987327,500390133,1155374404,389092991,150729210,3891597772,3523549952,1935325696,716645080,946045387,2901812282,1774124410,3869435775,4039581901,3293136918,3438657920,948246080,363898952,3867875531,1286266623,1598556673,68334250,630723836,1104211938,1312863373,613332731,2377784574,1101634306,441780740,3129959883,1917973735,2510624549,3238456535,2544211978,3308894634,1299840618,4076074851,1756332096,3977027158,297047435,3790297736,2265573040,3621810518,1311375015,1667687725,47300608,3299642885,2474112369,201668394,1468347890,576830978,3594690761,3742605952,1958042578,1747032512,3558991340,1408974056,3366841779,682131401,1033214337,1545599232,4265137049,206503691,103024618,2855227313,1337551222,2428998917,2963842932,4015366655,3852247746,2796956967,3865723491,3747938335,247794022,3755824572,702416469,2434691994,397379957,851939612,2314769512,218229120,1380406772,62274761,214451378,3170103466,2276210409,3845813286,28563499,446592073,1693330814,3453727194,29968656,3093872512,220656637,2470637031,77972100,1667708854,1358280214,4064765667,2395616961,325977563,4277240721,4220025399,3605526484,3355147721,811859167,3069544926,3962126810,652502677,3075892249,4132761541,3498924215,1217549313,3250244479,3858715919,3053989961,1538642152,2279026266,2875879137,574252750,3324769229,2651358713,1758150215,141295887,2719868960,3515574750,4093007735,4194485238,1082055363,3417560400,395511885,2966884026,179534037,3646028556,3738688086,1092926436,2496269142,257381841,3772900718,1636087230,1477059743,2499234752,3811018894,2675660129,3285975680,90732309,1684827095,1150307763,1723134115,3237045386,1769919919,1240018934,815675215,750138730,2239792499,1234303040,1995484674,138143821,675421338,1145607174,1936608440,3238603024,2345230278,2105974004,323969391,779555213,3004902369,2861610098,1017501463,2098600890,2628620304,2940611490,2682542546,1171473753,3656571411,3687208071,4091869518,393037935,159126506,1662887367,1147106178,391545844,3452332695,1891500680,3016609650,1851642611,546529401,1167818917,3194020571,2848076033,3953471836,575554290,475796850,4134673196,450035699,2351251534,844027695,1080539133,86184846,1554234488,3692025454,1972511363,2018339607,1491841390,1141460869,1061690759,4244549243,2008416118,2351104703,2868147542,1598468138,722020353,1027143159,212344630,1387219594,1725294528,3745187956,2500153616,458938280,4129215917,1828119673,544571780,3503225445,2297937496,1241802790,267843827,2694610800,1397140384,1558801448,3782667683,1806446719,929573330,2234912681,400817706,616011623,4121520928,3603768725,1761550015,1968522284,4053731006,4192232858,4005120285,872482584,3140537016,3894607381,2287405443,1963876937,3663887957,1584857e3,2975024454,1833426440,4025083860),f[5]=new Array(4143615901,749497569,1285769319,3795025788,2514159847,23610292,3974978748,844452780,3214870880,3751928557,2213566365,1676510905,448177848,3730751033,4086298418,2307502392,871450977,3222878141,4110862042,3831651966,2735270553,1310974780,2043402188,1218528103,2736035353,4274605013,2702448458,3936360550,2693061421,162023535,2827510090,687910808,23484817,3784910947,3371371616,779677500,3503626546,3473927188,4157212626,3500679282,4248902014,2466621104,3899384794,1958663117,925738300,1283408968,3669349440,1840910019,137959847,2679828185,1239142320,1315376211,1547541505,1690155329,739140458,3128809933,3933172616,3876308834,905091803,1548541325,4040461708,3095483362,144808038,451078856,676114313,2861728291,2469707347,993665471,373509091,2599041286,4025009006,4170239449,2149739950,3275793571,3749616649,2794760199,1534877388,572371878,2590613551,1753320020,3467782511,1405125690,4270405205,633333386,3026356924,3475123903,632057672,2846462855,1404951397,3882875879,3915906424,195638627,2385783745,3902872553,1233155085,3355999740,2380578713,2702246304,2144565621,3663341248,3894384975,2502479241,4248018925,3094885567,1594115437,572884632,3385116731,767645374,1331858858,1475698373,3793881790,3532746431,1321687957,619889600,1121017241,3440213920,2070816767,2833025776,1933951238,4095615791,890643334,3874130214,859025556,360630002,925594799,1764062180,3920222280,4078305929,979562269,2810700344,4087740022,1949714515,546639971,1165388173,3069891591,1495988560,922170659,1291546247,2107952832,1813327274,3406010024,3306028637,4241950635,153207855,2313154747,1608695416,1150242611,1967526857,721801357,1220138373,3691287617,3356069787,2112743302,3281662835,1111556101,1778980689,250857638,2298507990,673216130,2846488510,3207751581,3562756981,3008625920,3417367384,2198807050,529510932,3547516680,3426503187,2364944742,102533054,2294910856,1617093527,1204784762,3066581635,1019391227,1069574518,1317995090,1691889997,3661132003,510022745,3238594800,1362108837,1817929911,2184153760,805817662,1953603311,3699844737,120799444,2118332377,207536705,2282301548,4120041617,145305846,2508124933,3086745533,3261524335,1877257368,2977164480,3160454186,2503252186,4221677074,759945014,254147243,2767453419,3801518371,629083197,2471014217,907280572,3900796746,940896768,2751021123,2625262786,3161476951,3661752313,3260732218,1425318020,2977912069,1496677566,3988592072,2140652971,3126511541,3069632175,977771578,1392695845,1698528874,1411812681,1369733098,1343739227,3620887944,1142123638,67414216,3102056737,3088749194,1626167401,2546293654,3941374235,697522451,33404913,143560186,2595682037,994885535,1247667115,3859094837,2699155541,3547024625,4114935275,2968073508,3199963069,2732024527,1237921620,951448369,1898488916,1211705605,2790989240,2233243581,3598044975),f[6]=new Array(2246066201,858518887,1714274303,3485882003,713916271,2879113490,3730835617,539548191,36158695,1298409750,419087104,1358007170,749914897,2989680476,1261868530,2995193822,2690628854,3443622377,3780124940,3796824509,2976433025,4259637129,1551479e3,512490819,1296650241,951993153,2436689437,2460458047,144139966,3136204276,310820559,3068840729,643875328,1969602020,1680088954,2185813161,3283332454,672358534,198762408,896343282,276269502,3014846926,84060815,197145886,376173866,3943890818,3813173521,3545068822,1316698879,1598252827,2633424951,1233235075,859989710,2358460855,3503838400,3409603720,1203513385,1193654839,2792018475,2060853022,207403770,1144516871,3068631394,1121114134,177607304,3785736302,326409831,1929119770,2983279095,4183308101,3474579288,3200513878,3228482096,119610148,1170376745,3378393471,3163473169,951863017,3337026068,3135789130,2907618374,1183797387,2015970143,4045674555,2182986399,2952138740,3928772205,384012900,2454997643,10178499,2879818989,2596892536,111523738,2995089006,451689641,3196290696,235406569,1441906262,3890558523,3013735005,4158569349,1644036924,376726067,1006849064,3664579700,2041234796,1021632941,1374734338,2566452058,371631263,4007144233,490221539,206551450,3140638584,1053219195,1853335209,3412429660,3562156231,735133835,1623211703,3104214392,2738312436,4096837757,3366392578,3110964274,3956598718,3196820781,2038037254,3877786376,2339753847,300912036,3766732888,2372630639,1516443558,4200396704,1574567987,4069441456,4122592016,2699739776,146372218,2748961456,2043888151,35287437,2596680554,655490400,1132482787,110692520,1031794116,2188192751,1324057718,1217253157,919197030,686247489,3261139658,1028237775,3135486431,3059715558,2460921700,986174950,2661811465,4062904701,2752986992,3709736643,367056889,1353824391,731860949,1650113154,1778481506,784341916,357075625,3608602432,1074092588,2480052770,3811426202,92751289,877911070,3600361838,1231880047,480201094,3756190983,3094495953,434011822,87971354,363687820,1717726236,1901380172,3926403882,2481662265,400339184,1490350766,2661455099,1389319756,2558787174,784598401,1983468483,30828846,3550527752,2716276238,3841122214,1765724805,1955612312,1277890269,1333098070,1564029816,2704417615,1026694237,3287671188,1260819201,3349086767,1016692350,1582273796,1073413053,1995943182,694588404,1025494639,3323872702,3551898420,4146854327,453260480,1316140391,1435673405,3038941953,3486689407,1622062951,403978347,817677117,950059133,4246079218,3278066075,1486738320,1417279718,481875527,2549965225,3933690356,760697757,1452955855,3897451437,1177426808,1702951038,4085348628,2447005172,1084371187,3516436277,3068336338,1073369276,1027665953,3284188590,1230553676,1368340146,2226246512,267243139,2274220762,4070734279,2497715176,2423353163,2504755875),f[7]=new Array(3793104909,3151888380,2817252029,895778965,2005530807,3871412763,237245952,86829237,296341424,3851759377,3974600970,2475086196,709006108,1994621201,2972577594,937287164,3734691505,168608556,3189338153,2225080640,3139713551,3033610191,3025041904,77524477,185966941,1208824168,2344345178,1721625922,3354191921,1066374631,1927223579,1971335949,2483503697,1551748602,2881383779,2856329572,3003241482,48746954,1398218158,2050065058,313056748,4255789917,393167848,1912293076,940740642,3465845460,3091687853,2522601570,2197016661,1727764327,364383054,492521376,1291706479,3264136376,1474851438,1685747964,2575719748,1619776915,1814040067,970743798,1561002147,2925768690,2123093554,1880132620,3151188041,697884420,2550985770,2607674513,2659114323,110200136,1489731079,997519150,1378877361,3527870668,478029773,2766872923,1022481122,431258168,1112503832,897933369,2635587303,669726182,3383752315,918222264,163866573,3246985393,3776823163,114105080,1903216136,761148244,3571337562,1690750982,3166750252,1037045171,1888456500,2010454850,642736655,616092351,365016990,1185228132,4174898510,1043824992,2023083429,2241598885,3863320456,3279669087,3674716684,108438443,2132974366,830746235,606445527,4173263986,2204105912,1844756978,2532684181,4245352700,2969441100,3796921661,1335562986,4061524517,2720232303,2679424040,634407289,885462008,3294724487,3933892248,2094100220,339117932,4048830727,3202280980,1458155303,2689246273,1022871705,2464987878,3714515309,353796843,2822958815,4256850100,4052777845,551748367,618185374,3778635579,4020649912,1904685140,3069366075,2670879810,3407193292,2954511620,4058283405,2219449317,3135758300,1120655984,3447565834,1474845562,3577699062,550456716,3466908712,2043752612,881257467,869518812,2005220179,938474677,3305539448,3850417126,1315485940,3318264702,226533026,965733244,321539988,1136104718,804158748,573969341,3708209826,937399083,3290727049,2901666755,1461057207,4013193437,4066861423,3242773476,2421326174,1581322155,3028952165,786071460,3900391652,3918438532,1485433313,4023619836,3708277595,3678951060,953673138,1467089153,1930354364,1533292819,2492563023,1346121658,1685000834,1965281866,3765933717,4190206607,2052792609,3515332758,690371149,3125873887,2180283551,2903598061,3933952357,436236910,289419410,14314871,1242357089,2904507907,1616633776,2666382180,585885352,3471299210,2699507360,1432659641,277164553,3354103607,770115018,2303809295,3741942315,3177781868,2853364978,2269453327,3774259834,987383833,1290892879,225909803,1741533526,890078084,1496906255,1111072499,916028167,243534141,1252605537,2204162171,531204876,290011180,3916834213,102027703,237315147,209093447,1486785922,220223953,2758195998,4175039106,82940208,3127791296,2569425252,518464269,1353887104,3941492737,2377294467,3935040926)}function d(a){this.cast5=new c,this.cast5.setKey(e.str2bin(a)),this.encrypt=function(a){return this.cast5.encrypt(a)}}var e=a("../../util");b.exports=d,b.exports.blockSize=d.prototype.blockSize=8,b.exports.keySize=d.prototype.keySize=16},{"../../util":56}],8:[function(a,b){function c(a,b,c,d,g,h){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w=new Array(16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756),x=new Array(-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344),y=new Array(520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584),z=new Array(8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928),A=new Array(256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080),B=new Array(536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312),C=new Array(2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154),D=new Array(268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696),E=0,F=b.length,G=0,H=32==a.length?3:9; -for(p=3==H?c?new Array(0,32,2):new Array(30,-2,-2):c?new Array(0,32,2,62,30,-2,64,96,2):new Array(94,62,-2,32,64,2,30,-2,-2),c&&(b=e(b,h),F=b.length),result="",tempresult="",1==d&&(q=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),s=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),E=0);F>E;){for(n=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),o=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),1==d&&(c?(n^=q,o^=s):(r=q,t=s,q=n,s=o)),k=252645135&(n>>>4^o),o^=k,n^=k<<4,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,n=n<<1|n>>>31,o=o<<1|o>>>31,j=0;H>j;j+=3){for(u=p[j+1],v=p[j+2],i=p[j];i!=u;i+=v)l=o^a[i],m=(o>>>4|o<<28)^a[i+1],k=n,n=o,o=k^(x[l>>>24&63]|z[l>>>16&63]|B[l>>>8&63]|D[63&l]|w[m>>>24&63]|y[m>>>16&63]|A[m>>>8&63]|C[63&m]);k=n,n=o,o=k}n=n>>>1|n<<31,o=o>>>1|o<<31,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=252645135&(n>>>4^o),o^=k,n^=k<<4,1==d&&(c?(q=n,s=o):(n^=r,o^=t)),tempresult+=String.fromCharCode(n>>>24,n>>>16&255,n>>>8&255,255&n,o>>>24,o>>>16&255,o>>>8&255,255&o),G+=8,512==G&&(result+=tempresult,tempresult="",G=0)}return result+=tempresult,c||(result=f(result,h)),result}function d(a){pc2bytes0=new Array(0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964),pc2bytes1=new Array(0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697),pc2bytes2=new Array(0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272),pc2bytes3=new Array(0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144),pc2bytes4=new Array(0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256),pc2bytes5=new Array(0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488),pc2bytes6=new Array(0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746),pc2bytes7=new Array(0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568),pc2bytes8=new Array(0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578),pc2bytes9=new Array(0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488),pc2bytes10=new Array(0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800),pc2bytes11=new Array(0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744),pc2bytes12=new Array(0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128),pc2bytes13=new Array(0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261);for(var b,c,d,e=a.length>8?3:1,f=new Array(32*e),g=new Array(0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0),h=0,j=0,k=0;e>k;k++)for(left=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),right=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),d=252645135&(left>>>4^right),right^=d,left^=d<<4,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=858993459&(left>>>2^right),right^=d,left^=d<<2,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=16711935&(right>>>8^left),left^=d,right^=d<<8,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=left<<8|right>>>20&240,left=right<<24|right<<8&16711680|right>>>8&65280|right>>>24&240,right=d,i=0;i>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,b=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],c=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],d=65535&(c>>>16^b),f[j++]=b^d,f[j++]=c^d<<16;return f}function e(a,b){var c=8-a.length%8;return 2==b&&8>c?a+=" ".substr(0,c):1==b?a+=String.fromCharCode(c,c,c,c,c,c,c,c).substr(0,c):!b&&8>c&&(a+="\x00\x00\x00\x00\x00\x00\x00\x00".substr(0,c)),a}function f(a,b){if(2==b)a=a.replace(/ *$/g,"");else if(1==b){var c=a.charCodeAt(a.length-1);a=a.substr(0,a.length-c)}else b||(a=a.replace(/\0*$/g,""));return a}function g(a){this.key=[];for(var b=0;3>b;b++)this.key.push(a.substr(8*b,8));this.encrypt=function(a){return j.str2bin(c(d(this.key[2]),c(d(this.key[1]),c(d(this.key[0]),j.bin2str(a),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(a){this.key=a,this.encrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!0,0,null,b))},this.decrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!1,0,null,b))}}var j=a("../../util");g.keySize=g.prototype.keySize=24,g.blockSize=g.prototype.blockSize=8,b.exports={des:g,originalDes:h}},{"../../util":56}],9:[function(a,b){var c=a("./des.js");b.exports={des:c.des,originalDes:c.originalDes,cast5:a("./cast5.js"),twofish:a("./twofish.js"),blowfish:a("./blowfish.js")};var d=a("./aes.js");for(var e in d)b.exports["aes"+e]=d[e]},{"./aes.js":5,"./blowfish.js":6,"./cast5.js":7,"./des.js":8,"./twofish.js":10}],10:[function(a,b){function c(a,b){return(a<>>32-b)&i}function d(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16|a[b+3]<<24}function e(a,b,c){a.splice(b,4,255&c,c>>>8&255,c>>>16&255,c>>>24&255)}function f(a,b){return a>>>8*b&255}function g(){function a(a){function b(a){return a^a>>2^[0,90,180,238][3&a]}function e(a){return a^a>>1^a>>2^[0,238,180,90][3&a]}function g(a,b){var c,d,e;for(c=0;8>c;c++)d=b>>>24,b=b<<8&i|a>>>24,a=a<<8&i,e=d<<1,128&d&&(e^=333),b^=d^e<<16,e^=d>>>1,1&d&&(e^=166),b^=e<<24|e<<8;return b}function h(a,b){var c,d,e,f;return c=b>>4,d=15&b,e=A[a][c^d],f=B[a][E[d]^F[c]],D[a][E[f]^F[e]]<<4|C[a][e^f]}function j(a,b){var c=f(a,0),d=f(a,1),e=f(a,2),g=f(a,3);switch(q){case 4:c=G[1][c]^f(b[3],0),d=G[0][d]^f(b[3],1),e=G[0][e]^f(b[3],2),g=G[1][g]^f(b[3],3);case 3:c=G[1][c]^f(b[2],0),d=G[1][d]^f(b[2],1),e=G[0][e]^f(b[2],2),g=G[0][g]^f(b[2],3);case 2:c=G[0][G[0][c]^f(b[1],0)]^f(b[0],0),d=G[0][G[1][d]^f(b[1],1)]^f(b[0],1),e=G[1][G[0][e]^f(b[1],2)]^f(b[0],2),g=G[1][G[1][g]^f(b[1],3)]^f(b[0],3)}return H[0][c]^H[1][d]^H[2][e]^H[3][g]}o=a;var k,l,m,n,p,q,r,u,v,w=[],x=[],y=[],z=[],A=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],B=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],C=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],D=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],E=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],F=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],G=[[],[]],H=[[],[],[],[]];for(o=o.slice(0,32),k=o.length;16!=k&&24!=k&&32!=k;)o[k++]=0;for(k=0;k>2]=d(o,k);for(k=0;256>k;k++)G[0][k]=h(0,k),G[1][k]=h(1,k);for(k=0;256>k;k++)r=G[1][k],u=b(r),v=e(r),H[0][k]=r+(u<<8)+(v<<16)+(v<<24),H[2][k]=u+(v<<8)+(r<<16)+(v<<24),r=G[0][k],u=b(r),v=e(r),H[1][k]=v+(v<<8)+(u<<16)+(r<<24),H[3][k]=u+(r<<8)+(v<<16)+(u<<24);for(q=y.length/2,k=0;q>k;k++)l=y[k+k],w[k]=l,m=y[k+k+1],x[k]=m,z[q-k-1]=g(l,m);for(k=0;40>k;k+=2)l=16843009*k,m=l+16843009,l=j(l,w),m=c(j(m,x),8),s[k]=l+m&i,s[k+1]=c(l+2*m,9);for(k=0;256>k;k++)switch(l=m=n=p=k,q){case 4:l=G[1][l]^f(z[3],0),m=G[0][m]^f(z[3],1),n=G[0][n]^f(z[3],2),p=G[1][p]^f(z[3],3);case 3:l=G[1][l]^f(z[2],0),m=G[1][m]^f(z[2],1),n=G[0][n]^f(z[2],2),p=G[0][p]^f(z[2],3);case 2:t[0][k]=H[0][G[0][G[0][l]^f(z[1],0)]^f(z[0],0)],t[1][k]=H[1][G[0][G[1][m]^f(z[1],1)]^f(z[0],1)],t[2][k]=H[2][G[1][G[0][n]^f(z[1],2)]^f(z[0],2)],t[3][k]=H[3][G[1][G[1][p]^f(z[1],3)]^f(z[0],3)]}}function b(a){return t[0][f(a,0)]^t[1][f(a,1)]^t[2][f(a,2)]^t[3][f(a,3)]}function g(a){return t[0][f(a,3)]^t[1][f(a,0)]^t[2][f(a,1)]^t[3][f(a,2)]}function h(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2]^e+f+s[4*a+8]&i,31),d[3]=c(d[3],1)^e+2*f+s[4*a+9]&i,e=b(d[2]),f=g(d[3]),d[0]=c(d[0]^e+f+s[4*a+10]&i,31),d[1]=c(d[1],1)^e+2*f+s[4*a+11]&i}function j(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2],1)^e+f+s[4*a+10]&i,d[3]=c(d[3]^e+2*f+s[4*a+11]&i,31),e=b(d[2]),f=g(d[3]),d[0]=c(d[0],1)^e+f+s[4*a+8]&i,d[1]=c(d[1]^e+2*f+s[4*a+9]&i,31)}function k(){s=[],t=[[],[],[],[]]}function l(a,b){p=a,q=b;for(var c=[d(p,q)^s[0],d(p,q+4)^s[1],d(p,q+8)^s[2],d(p,q+12)^s[3]],f=0;8>f;f++)h(f,c);return e(p,q,c[2]^s[4]),e(p,q+4,c[3]^s[5]),e(p,q+8,c[0]^s[6]),e(p,q+12,c[1]^s[7]),q+=16,p}function m(a,b){p=a,q=b;for(var c=[d(p,q)^s[4],d(p,q+4)^s[5],d(p,q+8)^s[6],d(p,q+12)^s[7]],f=7;f>=0;f--)j(f,c);e(p,q,c[2]^s[0]),e(p,q+4,c[3]^s[1]),e(p,q+8,c[0]^s[2]),e(p,q+12,c[1]^s[3]),q+=16}function n(){return p}var o=null,p=null,q=-1,r=null;r="twofish";var s=[],t=[[],[],[],[]];return{name:"twofish",blocksize:16,open:a,close:k,encrypt:l,decrypt:m,finalize:n}}function h(a){this.tf=g(),this.tf.open(j.str2bin(a),0),this.encrypt=function(a){return this.tf.encrypt([].concat(a),0)}}var i=4294967295,j=a("../../util");b.exports=h,b.exports.keySize=h.prototype.keySize=32,b.exports.blockSize=h.prototype.blockSize=16},{"../../util":56}],11:[function(a,b){var c=a("./random.js"),d=a("./cipher"),e=a("./public_key"),f=a("../type/mpi.js");b.exports={publicKeyEncrypt:function(a,b,c){var d=function(){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":var d=new e.rsa,f=b[0].toBigInteger(),g=b[1].toBigInteger(),h=c.toBigInteger();return[d.encrypt(h,g,f)];case"elgamal":var i=new e.elgamal,j=b[0].toBigInteger(),k=b[1].toBigInteger(),l=b[2].toBigInteger(),h=c.toBigInteger();return i.encrypt(h,k,j,l);default:return[]}}();return d.map(function(a){var b=new f;return b.fromBigInteger(a),b})},publicKeyDecrypt:function(a,b,c){var d=function(){switch(a){case"rsa_encrypt_sign":case"rsa_encrypt":var d=new e.rsa,f=b[2].toBigInteger(),g=b[3].toBigInteger(),h=b[4].toBigInteger(),i=b[5].toBigInteger(),j=c[0].toBigInteger();return d.decrypt(j,f,g,h,i);case"elgamal":var k=new e.elgamal,l=b[3].toBigInteger(),m=c[0].toBigInteger(),n=c[1].toBigInteger(),g=b[0].toBigInteger();return k.decrypt(m,n,g,l);default:return null}}(),g=new f;return g.fromBigInteger(d),g},getPrivateMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 4;case"elgamal":return 1;case"dsa":return 1;default:throw new Error("Unknown algorithm")}},getPublicMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 2;case"elgamal":return 3;case"dsa":return 4;default:throw new Error("Unknown algorithm.")}},generateMpi:function(a,b){var c=function(){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":var c=new e.rsa,d=c.generate(b,"10001"),f=[];return f.push(d.n),f.push(d.ee),f.push(d.d),f.push(d.p),f.push(d.q),f.push(d.u),f;default:throw new Error("Unsupported algorithm for key generation.")}}();return c.map(function(a){var b=new f;return b.fromBigInteger(a),b})},getPrefixRandom:function(a){return c.getRandomBytes(d[a].blockSize)},generateSessionKey:function(a){return c.getRandomBytes(d[a].keySize)}}},{"../type/mpi.js":54,"./cipher":9,"./public_key":20,"./random.js":23}],12:[function(a,b){var c=a("./sha.js");b.exports={md5:a("./md5.js"),sha1:c.sha1,sha256:c.sha256,sha224:c.sha224,sha384:c.sha384,sha512:c.sha512,ripemd:a("./ripe-md.js"),digest:function(a,b){switch(a){case 1:return this.md5(b);case 2:return this.sha1(b);case 3:return this.ripemd(b);case 8:return this.sha256(b);case 9:return this.sha384(b);case 10:return this.sha512(b);case 11:return this.sha224(b);default:throw new Error("Invalid hash function.")}},getHashByteLength:function(a){switch(a){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw new Error("Invalid hash algorithm.")}}}},{"./md5.js":13,"./ripe-md.js":14,"./sha.js":15}],13:[function(a,b){function c(a){var b=n(a),c=p.hex2bin(b);return c}function d(a,b){var c=a[0],d=a[1],e=a[2],j=a[3];c=f(c,d,e,j,b[0],7,-680876936),j=f(j,c,d,e,b[1],12,-389564586),e=f(e,j,c,d,b[2],17,606105819),d=f(d,e,j,c,b[3],22,-1044525330),c=f(c,d,e,j,b[4],7,-176418897),j=f(j,c,d,e,b[5],12,1200080426),e=f(e,j,c,d,b[6],17,-1473231341),d=f(d,e,j,c,b[7],22,-45705983),c=f(c,d,e,j,b[8],7,1770035416),j=f(j,c,d,e,b[9],12,-1958414417),e=f(e,j,c,d,b[10],17,-42063),d=f(d,e,j,c,b[11],22,-1990404162),c=f(c,d,e,j,b[12],7,1804603682),j=f(j,c,d,e,b[13],12,-40341101),e=f(e,j,c,d,b[14],17,-1502002290),d=f(d,e,j,c,b[15],22,1236535329),c=g(c,d,e,j,b[1],5,-165796510),j=g(j,c,d,e,b[6],9,-1069501632),e=g(e,j,c,d,b[11],14,643717713),d=g(d,e,j,c,b[0],20,-373897302),c=g(c,d,e,j,b[5],5,-701558691),j=g(j,c,d,e,b[10],9,38016083),e=g(e,j,c,d,b[15],14,-660478335),d=g(d,e,j,c,b[4],20,-405537848),c=g(c,d,e,j,b[9],5,568446438),j=g(j,c,d,e,b[14],9,-1019803690),e=g(e,j,c,d,b[3],14,-187363961),d=g(d,e,j,c,b[8],20,1163531501),c=g(c,d,e,j,b[13],5,-1444681467),j=g(j,c,d,e,b[2],9,-51403784),e=g(e,j,c,d,b[7],14,1735328473),d=g(d,e,j,c,b[12],20,-1926607734),c=h(c,d,e,j,b[5],4,-378558),j=h(j,c,d,e,b[8],11,-2022574463),e=h(e,j,c,d,b[11],16,1839030562),d=h(d,e,j,c,b[14],23,-35309556),c=h(c,d,e,j,b[1],4,-1530992060),j=h(j,c,d,e,b[4],11,1272893353),e=h(e,j,c,d,b[7],16,-155497632),d=h(d,e,j,c,b[10],23,-1094730640),c=h(c,d,e,j,b[13],4,681279174),j=h(j,c,d,e,b[0],11,-358537222),e=h(e,j,c,d,b[3],16,-722521979),d=h(d,e,j,c,b[6],23,76029189),c=h(c,d,e,j,b[9],4,-640364487),j=h(j,c,d,e,b[12],11,-421815835),e=h(e,j,c,d,b[15],16,530742520),d=h(d,e,j,c,b[2],23,-995338651),c=i(c,d,e,j,b[0],6,-198630844),j=i(j,c,d,e,b[7],10,1126891415),e=i(e,j,c,d,b[14],15,-1416354905),d=i(d,e,j,c,b[5],21,-57434055),c=i(c,d,e,j,b[12],6,1700485571),j=i(j,c,d,e,b[3],10,-1894986606),e=i(e,j,c,d,b[10],15,-1051523),d=i(d,e,j,c,b[1],21,-2054922799),c=i(c,d,e,j,b[8],6,1873313359),j=i(j,c,d,e,b[15],10,-30611744),e=i(e,j,c,d,b[6],15,-1560198380),d=i(d,e,j,c,b[13],21,1309151649),c=i(c,d,e,j,b[4],6,-145523070),j=i(j,c,d,e,b[11],10,-1120210379),e=i(e,j,c,d,b[2],15,718787259),d=i(d,e,j,c,b[9],21,-343485551),a[0]=o(c,a[0]),a[1]=o(d,a[1]),a[2]=o(e,a[2]),a[3]=o(j,a[3])}function e(a,b,c,d,e,f){return b=o(o(b,a),o(d,f)),o(b<>>32-e,c)}function f(a,b,c,d,f,g,h){return e(b&c|~b&d,a,b,f,g,h)}function g(a,b,c,d,f,g,h){return e(b&d|c&~d,a,b,f,g,h)}function h(a,b,c,d,f,g,h){return e(b^c^d,a,b,f,g,h)}function i(a,b,c,d,f,g,h){return e(c^(b|~d),a,b,f,g,h)}function j(a){txt="";var b,c=a.length,e=[1732584193,-271733879,-1732584194,271733878];for(b=64;b<=a.length;b+=64)d(e,k(a.substring(b-64,b)));a=a.substring(b-64);var f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(b=0;b>2]|=a.charCodeAt(b)<<(b%4<<3);if(f[b>>2]|=128<<(b%4<<3),b>55)for(d(e,f),b=0;16>b;b++)f[b]=0;return f[14]=8*c,d(e,f),e}function k(a){var b,c=[];for(b=0;64>b;b+=4)c[b>>2]=a.charCodeAt(b)+(a.charCodeAt(b+1)<<8)+(a.charCodeAt(b+2)<<16)+(a.charCodeAt(b+3)<<24);return c}function l(a){for(var b="",c=0;4>c;c++)b+=q[a>>8*c+4&15]+q[a>>8*c&15];return b}function m(a){for(var b=0;b>16)+(b>>16)+(c>>16);return d<<16|65535&c}var p=a("../../util/util.js"),q="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=n("hello"),b.exports=c},{"../../util/util.js":56}],14:[function(a,b){function c(a,b){return new Number(a<>>32-b)}function d(a,b,c){return new Number(a^b^c)}function e(a,b,c){return new Number(a&b|~a&c)}function f(a,b,c){return new Number((a|~b)^c)}function g(a,b,c){return new Number(a&c|b&~c)}function h(a,b,c){return new Number(a^(b|~c))}function i(a,b,i,j,k,l,m,n){switch(n){case 0:a+=d(b,i,j)+l+0;break;case 1:a+=e(b,i,j)+l+1518500249;break;case 2:a+=f(b,i,j)+l+1859775393;break;case 3:a+=g(b,i,j)+l+2400959708;break;case 4:a+=h(b,i,j)+l+2840853838;break;case 5:a+=h(b,i,j)+l+1352829926;break;case 6:a+=g(b,i,j)+l+1548603684;break;case 7:a+=f(b,i,j)+l+1836072691;break;case 8:a+=e(b,i,j)+l+2053994217;break;case 9:a+=d(b,i,j)+l+0;break;default:document.write("Bogus round number")}a=c(a,m)+k,i=c(i,10),a&=4294967295,b&=4294967295,i&=4294967295,j&=4294967295,k&=4294967295;var o=new Array;return o[0]=a,o[1]=b,o[2]=i,o[3]=j,o[4]=k,o[5]=l,o[6]=m,o}function j(a){a[0]=1732584193,a[1]=4023233417,a[2]=2562383102,a[3]=271733878,a[4]=3285377520}function k(a,b){blockA=new Array,blockB=new Array;for(var c,d=0;5>d;d++)blockA[d]=new Number(a[d]),blockB[d]=new Number(a[d]);for(var e=0,f=0;5>f;f++)for(var d=0;16>d;d++)c=i(blockA[(e+0)%5],blockA[(e+1)%5],blockA[(e+2)%5],blockA[(e+3)%5],blockA[(e+4)%5],b[s[f][d]],r[f][d],f),blockA[(e+0)%5]=c[0],blockA[(e+1)%5]=c[1],blockA[(e+2)%5]=c[2],blockA[(e+3)%5]=c[3],blockA[(e+4)%5]=c[4],e+=4;e=0;for(var f=5;10>f;f++)for(var d=0;16>d;d++)c=i(blockB[(e+0)%5],blockB[(e+1)%5],blockB[(e+2)%5],blockB[(e+3)%5],blockB[(e+4)%5],b[s[f][d]],r[f][d],f),blockB[(e+0)%5]=c[0],blockB[(e+1)%5]=c[1],blockB[(e+2)%5]=c[2],blockB[(e+3)%5]=c[3],blockB[(e+4)%5]=c[4],e+=4;blockB[3]+=blockA[2]+a[1],a[1]=a[2]+blockA[3]+blockB[4],a[2]=a[3]+blockA[4]+blockB[0],a[3]=a[4]+blockA[0]+blockB[1],a[4]=a[0]+blockA[1]+blockB[2],a[0]=blockB[3]}function l(a){for(var b=0;16>b;b++)a[b]=0}function m(a,b,c,d){var e=new Array(16);l(e);for(var f=0,g=0;(63&c)>g;g++)e[g>>>2]^=(255&b.charCodeAt(f++))<<8*(3&g);if(e[c>>>2&15]^=1<<8*(3&c)+7,(63&c)>55){k(a,e);var e=new Array(16);l(e)}e[14]=c<<3,e[15]=c>>>29|d<<3,k(a,e)}function n(a){var b=(255&a.charCodeAt(3))<<24;return b|=(255&a.charCodeAt(2))<<16,b|=(255&a.charCodeAt(1))<<8,b|=255&a.charCodeAt(0)}function o(a){var b,c,d=new Array(q/32),e=new Array(q/8);j(d),b=a.length;var f=new Array(16);l(f);for(var g=0,c=b;c>63;c-=64){for(var h=0;16>h;h++)f[h]=n(a.substr(g,4)),g+=4;k(d,f)}m(d,a.substr(g),b,0);for(var h=0;q/8>h;h+=4)e[h]=255&d[h>>>2],e[h+1]=d[h>>>2]>>>8&255,e[h+2]=d[h>>>2]>>>16&255,e[h+3]=d[h>>>2]>>>24&255;return e}function p(a){for(var b=o(a),c="",d=0;q/8>d;d++)c+=String.fromCharCode(b[d]);return c}var q=160,r=(new Array,[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]]),s=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]];b.exports=p},{}],15:[function(a,b){var c=function(){var a=8,b="",c=0,d=function(a,b){this.highOrder=a,this.lowOrder=b},e=function(b){var c,d=[],e=(1<c;c+=a)d[c>>5]|=(b.charCodeAt(c/a)&e)<<32-a-c%32;return d},f=function(a){var b,c,d=[],e=a.length;for(b=0;e>b;b+=2){if(c=parseInt(a.substr(b,2),16),isNaN(c))return"INVALID HEX STRING";d[b>>3]|=c<<24-4*(b%8)}return d},g=function(a){var b,d,e=c?"0123456789ABCDEF":"0123456789abcdef",f="",g=4*a.length;for(b=0;g>b;b+=1)d=a[b>>2]>>8*(3-b%4),f+=e.charAt(d>>4&15)+e.charAt(15&d);return f},h=function(a){var c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g="",h=4*a.length;for(c=0;h>c;c+=3)for(e=(a[c>>2]>>8*(3-c%4)&255)<<16|(a[c+1>>2]>>8*(3-(c+1)%4)&255)<<8|a[c+2>>2]>>8*(3-(c+2)%4)&255,d=0;4>d;d+=1)g+=8*c+6*d<=32*a.length?f.charAt(e>>6*(3-d)&63):b;return g},i=function(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b},j=function(a,b){return a<>>32-b},k=function(a,b){return a>>>b|a<<32-b},l=function(a,b){return 32>=b?new d(a.highOrder>>>b|a.lowOrder<<32-b,a.lowOrder>>>b|a.highOrder<<32-b):new d(a.lowOrder>>>b|a.highOrder<<32-b,a.highOrder>>>b|a.lowOrder<<32-b)},m=function(a,b){return a>>>b},n=function(a,b){return 32>=b?new d(a.highOrder>>>b,a.lowOrder>>>b|a.highOrder<<32-b):new d(0,a.highOrder<<32-b)},o=function(a,b,c){return a^b^c},p=function(a,b,c){return a&b^~a&c},q=function(a,b,c){return new d(a.highOrder&b.highOrder^~a.highOrder&c.highOrder,a.lowOrder&b.lowOrder^~a.lowOrder&c.lowOrder)},r=function(a,b,c){return a&b^a&c^b&c},s=function(a,b,c){return new d(a.highOrder&b.highOrder^a.highOrder&c.highOrder^b.highOrder&c.highOrder,a.lowOrder&b.lowOrder^a.lowOrder&c.lowOrder^b.lowOrder&c.lowOrder)},t=function(a){return k(a,2)^k(a,13)^k(a,22)},u=function(a){var b=l(a,28),c=l(a,34),e=l(a,39);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},v=function(a){return k(a,6)^k(a,11)^k(a,25)},w=function(a){var b=l(a,14),c=l(a,18),e=l(a,41);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},x=function(a){return k(a,7)^k(a,18)^m(a,3)},y=function(a){var b=l(a,1),c=l(a,8),e=n(a,7);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},z=function(a){return k(a,17)^k(a,19)^m(a,10)},A=function(a){var b=l(a,19),c=l(a,61),e=n(a,6);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},B=function(a,b){var c=(65535&a)+(65535&b),d=(a>>>16)+(b>>>16)+(c>>>16);return(65535&d)<<16|65535&c},C=function(a,b,c,d){var e=(65535&a)+(65535&b)+(65535&c)+(65535&d),f=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16);return(65535&f)<<16|65535&e},D=function(a,b,c,d,e){var f=(65535&a)+(65535&b)+(65535&c)+(65535&d)+(65535&e),g=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return(65535&g)<<16|65535&f},E=function(a,b){var c,e,f,g;return c=(65535&a.lowOrder)+(65535&b.lowOrder),e=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c>>>16),f=(65535&e)<<16|65535&c,c=(65535&a.highOrder)+(65535&b.highOrder)+(e>>>16),e=(a.highOrder>>>16)+(b.highOrder>>>16)+(c>>>16),g=(65535&e)<<16|65535&c,new d(g,f)},F=function(a,b,c,e){var f,g,h,i;return f=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder),g=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16),h=(65535&g)<<16|65535&f,f=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(g>>>16),g=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16),i=(65535&g)<<16|65535&f,new d(i,h)},G=function(a,b,c,e,f){var g,h,i,j;return g=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder)+(65535&f.lowOrder),h=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16),i=(65535&h)<<16|65535&g,g=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(65535&f.highOrder)+(h>>>16),h=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16),j=(65535&h)<<16|65535&g,new d(j,i)},H=function(a,b){var c,d,e,f,g,h,i,k,l,m=[],n=p,q=o,s=r,t=j,u=B,v=D,w=[1732584193,4023233417,2562383102,271733878,3285377520],x=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(a[b>>5]|=128<<24-b%32,a[(b+65>>9<<4)+15]=b,l=a.length,i=0;l>i;i+=16){for(c=w[0],d=w[1],e=w[2],f=w[3],g=w[4],k=0;80>k;k+=1)m[k]=16>k?a[k+i]:t(m[k-3]^m[k-8]^m[k-14]^m[k-16],1),h=20>k?v(t(c,5),n(d,e,f),g,x[k],m[k]):40>k?v(t(c,5),q(d,e,f),g,x[k],m[k]):60>k?v(t(c,5),s(d,e,f),g,x[k],m[k]):v(t(c,5),q(d,e,f),g,x[k],m[k]),g=f,f=e,e=t(d,30),d=c,c=h;w[0]=u(c,w[0]),w[1]=u(d,w[1]),w[2]=u(e,w[2]),w[3]=u(f,w[3]),w[4]=u(g,w[4])}return w},I=function(a,b,c){var e,f,g,h,i,j,k,l,m,n,o,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z=[];for("SHA-224"===c||"SHA-256"===c?(H=64,I=(b+65>>9<<4)+15,L=16,M=1,W=Number,N=B,O=C,P=D,Q=x,R=z,S=t,T=v,V=r,U=p,X=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],o="SHA-224"===c?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===c||"SHA-512"===c)&&(H=80,I=(b+128>>10<<5)+31,L=32,M=2,W=d,N=E,O=F,P=G,Q=y,R=A,S=u,T=w,V=s,U=q,X=[new W(1116352408,3609767458),new W(1899447441,602891725),new W(3049323471,3964484399),new W(3921009573,2173295548),new W(961987163,4081628472),new W(1508970993,3053834265),new W(2453635748,2937671579),new W(2870763221,3664609560),new W(3624381080,2734883394),new W(310598401,1164996542),new W(607225278,1323610764),new W(1426881987,3590304994),new W(1925078388,4068182383),new W(2162078206,991336113),new W(2614888103,633803317),new W(3248222580,3479774868),new W(3835390401,2666613458),new W(4022224774,944711139),new W(264347078,2341262773),new W(604807628,2007800933),new W(770255983,1495990901),new W(1249150122,1856431235),new W(1555081692,3175218132),new W(1996064986,2198950837),new W(2554220882,3999719339),new W(2821834349,766784016),new W(2952996808,2566594879),new W(3210313671,3203337956),new W(3336571891,1034457026),new W(3584528711,2466948901),new W(113926993,3758326383),new W(338241895,168717936),new W(666307205,1188179964),new W(773529912,1546045734),new W(1294757372,1522805485),new W(1396182291,2643833823),new W(1695183700,2343527390),new W(1986661051,1014477480),new W(2177026350,1206759142),new W(2456956037,344077627),new W(2730485921,1290863460),new W(2820302411,3158454273),new W(3259730800,3505952657),new W(3345764771,106217008),new W(3516065817,3606008344),new W(3600352804,1432725776),new W(4094571909,1467031594),new W(275423344,851169720),new W(430227734,3100823752),new W(506948616,1363258195),new W(659060556,3750685593),new W(883997877,3785050280),new W(958139571,3318307427),new W(1322822218,3812723403),new W(1537002063,2003034995),new W(1747873779,3602036899),new W(1955562222,1575990012),new W(2024104815,1125592928),new W(2227730452,2716904306),new W(2361852424,442776044),new W(2428436474,593698344),new W(2756734187,3733110249),new W(3204031479,2999351573),new W(3329325298,3815920427),new W(3391569614,3928383900),new W(3515267271,566280711),new W(3940187606,3454069534),new W(4118630271,4000239992),new W(116418474,1914138554),new W(174292421,2731055270),new W(289380356,3203993006),new W(460393269,320620315),new W(685471733,587496836),new W(852142971,1086792851),new W(1017036298,365543100),new W(1126000580,2618297676),new W(1288033470,3409855158),new W(1501505948,4234509866),new W(1607167915,987167468),new W(1816402316,1246189591)],o="SHA-384"===c?[new W(3418070365,3238371032),new W(1654270250,914150663),new W(2438529370,812702999),new W(355462360,4144912697),new W(1731405415,4290775857),new W(41048885895,1750603025),new W(3675008525,1694076839),new W(1203062813,3204075428)]:[new W(1779033703,4089235720),new W(3144134277,2227873595),new W(1013904242,4271175723),new W(2773480762,1595750129),new W(1359893119,2917565137),new W(2600822924,725511199),new W(528734635,4215389547),new W(1541459225,327033209)]),a[b>>5]|=128<<24-b%32,a[I]=b,Y=a.length,J=0;Y>J;J+=L){for(e=o[0],f=o[1],g=o[2],h=o[3],i=o[4],j=o[5],k=o[6],l=o[7],K=0;H>K;K+=1)Z[K]=16>K?new W(a[K*M+J],a[K*M+J+1]):O(R(Z[K-2]),Z[K-7],Q(Z[K-15]),Z[K-16]),m=P(l,T(i),U(i,j,k),X[K],Z[K]),n=N(S(e),V(e,f,g)),l=k,k=j,j=i,i=N(h,m),h=g,g=f,f=e,e=N(m,n);o[0]=N(e,o[0]),o[1]=N(f,o[1]),o[2]=N(g,o[2]),o[3]=N(h,o[3]),o[4]=N(i,o[4]),o[5]=N(j,o[5]),o[6]=N(k,o[6]),o[7]=N(l,o[7])}switch(c){case"SHA-224":return[o[0],o[1],o[2],o[3],o[4],o[5],o[6]];case"SHA-256":return o;case"SHA-384":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder];case"SHA-512":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder,o[6].highOrder,o[6].lowOrder,o[7].highOrder,o[7].lowOrder];default:return[]}},J=function(b,c){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===c){if(0!==b.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*b.length,this.strToHash=f(b)}else{if("ASCII"!==c&&"undefined"!=typeof c)return"UNKNOWN TEXT INPUT TYPE";this.strBinLen=b.length*a,this.strToHash=e(b)}};return J.prototype={getHash:function(a,b){var c=null,d=this.strToHash.slice();switch(b){case"HEX":c=g;break;case"B64":c=h;break;case"ASCII":c=i;break;default:return"FORMAT NOT RECOGNIZED"}switch(a){case"SHA-1":return null===this.sha1&&(this.sha1=H(d,this.strBinLen)),c(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=I(d,this.strBinLen,a)),c(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=I(d,this.strBinLen,a)),c(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=I(d,this.strBinLen,a)),c(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=I(d,this.strBinLen,a)),c(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(b,c,d,j){var k,l,m,n,o,p,q,r,s,t=[],u=[];switch(j){case"HEX":k=g;break;case"B64":k=h;break;case"ASCII":k=i;break;default:return"FORMAT NOT RECOGNIZED"}switch(d){case"SHA-1":m=64,s=160;break;case"SHA-224":m=64,s=224;break;case"SHA-256":m=64,s=256;break;case"SHA-384":m=128,s=384;break;case"SHA-512":m=128,s=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===c){if(0!==b.length%2)return"KEY MUST BE IN BYTE INCREMENTS";l=f(b),r=4*b.length}else{if("ASCII"!==c)return"UNKNOWN KEY INPUT TYPE";l=e(b),r=b.length*a}for(n=8*m,q=m/4-1,r/8>m?(l="SHA-1"===d?H(l,r):I(l,r,d),l[q]&=4294967040):m>r/8&&(l[q]&=4294967040),o=0;q>=o;o+=1)t[o]=909522486^l[o],u[o]=1549556828^l[o];return"SHA-1"===d?(p=H(t.concat(this.strToHash),n+this.strBinLen),p=H(u.concat(p),n+s)):(p=I(t.concat(this.strToHash),n+this.strBinLen,d),p=I(u.concat(p),n+s,d)),k(p)}},J}();b.exports={sha1:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-1","ASCII")},sha224:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-224","ASCII")},sha256:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-256","ASCII")},sha384:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-384","ASCII")},sha512:function(a){var b=new c(a,"ASCII"); +for(p=3==H?c?new Array(0,32,2):new Array(30,-2,-2):c?new Array(0,32,2,62,30,-2,64,96,2):new Array(94,62,-2,32,64,2,30,-2,-2),c&&(b=e(b,h),F=b.length),result="",tempresult="",1==d&&(q=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),s=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),E=0);F>E;){for(n=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),o=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),1==d&&(c?(n^=q,o^=s):(r=q,t=s,q=n,s=o)),k=252645135&(n>>>4^o),o^=k,n^=k<<4,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,n=n<<1|n>>>31,o=o<<1|o>>>31,j=0;H>j;j+=3){for(u=p[j+1],v=p[j+2],i=p[j];i!=u;i+=v)l=o^a[i],m=(o>>>4|o<<28)^a[i+1],k=n,n=o,o=k^(x[l>>>24&63]|z[l>>>16&63]|B[l>>>8&63]|D[63&l]|w[m>>>24&63]|y[m>>>16&63]|A[m>>>8&63]|C[63&m]);k=n,n=o,o=k}n=n>>>1|n<<31,o=o>>>1|o<<31,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=252645135&(n>>>4^o),o^=k,n^=k<<4,1==d&&(c?(q=n,s=o):(n^=r,o^=t)),tempresult+=String.fromCharCode(n>>>24,n>>>16&255,n>>>8&255,255&n,o>>>24,o>>>16&255,o>>>8&255,255&o),G+=8,512==G&&(result+=tempresult,tempresult="",G=0)}return result+=tempresult,c||(result=f(result,h)),result}function d(a){pc2bytes0=new Array(0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964),pc2bytes1=new Array(0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697),pc2bytes2=new Array(0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272),pc2bytes3=new Array(0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144),pc2bytes4=new Array(0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256),pc2bytes5=new Array(0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488),pc2bytes6=new Array(0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746),pc2bytes7=new Array(0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568),pc2bytes8=new Array(0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578),pc2bytes9=new Array(0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488),pc2bytes10=new Array(0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800),pc2bytes11=new Array(0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744),pc2bytes12=new Array(0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128),pc2bytes13=new Array(0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261);for(var b,c,d,e=a.length>8?3:1,f=new Array(32*e),g=new Array(0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0),h=0,j=0,k=0;e>k;k++)for(left=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),right=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),d=252645135&(left>>>4^right),right^=d,left^=d<<4,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=858993459&(left>>>2^right),right^=d,left^=d<<2,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=16711935&(right>>>8^left),left^=d,right^=d<<8,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=left<<8|right>>>20&240,left=right<<24|right<<8&16711680|right>>>8&65280|right>>>24&240,right=d,i=0;i>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,b=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],c=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],d=65535&(c>>>16^b),f[j++]=b^d,f[j++]=c^d<<16;return f}function e(a,b){var c=8-a.length%8;return 2==b&&8>c?a+=" ".substr(0,c):1==b?a+=String.fromCharCode(c,c,c,c,c,c,c,c).substr(0,c):!b&&8>c&&(a+="\x00\x00\x00\x00\x00\x00\x00\x00".substr(0,c)),a}function f(a,b){if(2==b)a=a.replace(/ *$/g,"");else if(1==b){var c=a.charCodeAt(a.length-1);a=a.substr(0,a.length-c)}else b||(a=a.replace(/\0*$/g,""));return a}function g(a){this.key=[];for(var b=0;3>b;b++)this.key.push(a.substr(8*b,8));this.encrypt=function(a){return j.str2bin(c(d(this.key[2]),c(d(this.key[1]),c(d(this.key[0]),j.bin2str(a),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(a){this.key=a,this.encrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!0,0,null,b))},this.decrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!1,0,null,b))}}var j=a("../../util");g.keySize=g.prototype.keySize=24,g.blockSize=g.prototype.blockSize=8,b.exports={des:g,originalDes:h}},{"../../util":56}],9:[function(a,b){var c=a("./des.js");b.exports={des:c.des,originalDes:c.originalDes,cast5:a("./cast5.js"),twofish:a("./twofish.js"),blowfish:a("./blowfish.js")};var d=a("./aes.js");for(var e in d)b.exports["aes"+e]=d[e]},{"./aes.js":5,"./blowfish.js":6,"./cast5.js":7,"./des.js":8,"./twofish.js":10}],10:[function(a,b){function c(a,b){return(a<>>32-b)&i}function d(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16|a[b+3]<<24}function e(a,b,c){a.splice(b,4,255&c,c>>>8&255,c>>>16&255,c>>>24&255)}function f(a,b){return a>>>8*b&255}function g(){function a(a){function b(a){return a^a>>2^[0,90,180,238][3&a]}function e(a){return a^a>>1^a>>2^[0,238,180,90][3&a]}function g(a,b){var c,d,e;for(c=0;8>c;c++)d=b>>>24,b=b<<8&i|a>>>24,a=a<<8&i,e=d<<1,128&d&&(e^=333),b^=d^e<<16,e^=d>>>1,1&d&&(e^=166),b^=e<<24|e<<8;return b}function h(a,b){var c,d,e,f;return c=b>>4,d=15&b,e=A[a][c^d],f=B[a][E[d]^F[c]],D[a][E[f]^F[e]]<<4|C[a][e^f]}function j(a,b){var c=f(a,0),d=f(a,1),e=f(a,2),g=f(a,3);switch(q){case 4:c=G[1][c]^f(b[3],0),d=G[0][d]^f(b[3],1),e=G[0][e]^f(b[3],2),g=G[1][g]^f(b[3],3);case 3:c=G[1][c]^f(b[2],0),d=G[1][d]^f(b[2],1),e=G[0][e]^f(b[2],2),g=G[0][g]^f(b[2],3);case 2:c=G[0][G[0][c]^f(b[1],0)]^f(b[0],0),d=G[0][G[1][d]^f(b[1],1)]^f(b[0],1),e=G[1][G[0][e]^f(b[1],2)]^f(b[0],2),g=G[1][G[1][g]^f(b[1],3)]^f(b[0],3)}return H[0][c]^H[1][d]^H[2][e]^H[3][g]}o=a;var k,l,m,n,p,q,r,u,v,w=[],x=[],y=[],z=[],A=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],B=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],C=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],D=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],E=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],F=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],G=[[],[]],H=[[],[],[],[]];for(o=o.slice(0,32),k=o.length;16!=k&&24!=k&&32!=k;)o[k++]=0;for(k=0;k>2]=d(o,k);for(k=0;256>k;k++)G[0][k]=h(0,k),G[1][k]=h(1,k);for(k=0;256>k;k++)r=G[1][k],u=b(r),v=e(r),H[0][k]=r+(u<<8)+(v<<16)+(v<<24),H[2][k]=u+(v<<8)+(r<<16)+(v<<24),r=G[0][k],u=b(r),v=e(r),H[1][k]=v+(v<<8)+(u<<16)+(r<<24),H[3][k]=u+(r<<8)+(v<<16)+(u<<24);for(q=y.length/2,k=0;q>k;k++)l=y[k+k],w[k]=l,m=y[k+k+1],x[k]=m,z[q-k-1]=g(l,m);for(k=0;40>k;k+=2)l=16843009*k,m=l+16843009,l=j(l,w),m=c(j(m,x),8),s[k]=l+m&i,s[k+1]=c(l+2*m,9);for(k=0;256>k;k++)switch(l=m=n=p=k,q){case 4:l=G[1][l]^f(z[3],0),m=G[0][m]^f(z[3],1),n=G[0][n]^f(z[3],2),p=G[1][p]^f(z[3],3);case 3:l=G[1][l]^f(z[2],0),m=G[1][m]^f(z[2],1),n=G[0][n]^f(z[2],2),p=G[0][p]^f(z[2],3);case 2:t[0][k]=H[0][G[0][G[0][l]^f(z[1],0)]^f(z[0],0)],t[1][k]=H[1][G[0][G[1][m]^f(z[1],1)]^f(z[0],1)],t[2][k]=H[2][G[1][G[0][n]^f(z[1],2)]^f(z[0],2)],t[3][k]=H[3][G[1][G[1][p]^f(z[1],3)]^f(z[0],3)]}}function b(a){return t[0][f(a,0)]^t[1][f(a,1)]^t[2][f(a,2)]^t[3][f(a,3)]}function g(a){return t[0][f(a,3)]^t[1][f(a,0)]^t[2][f(a,1)]^t[3][f(a,2)]}function h(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2]^e+f+s[4*a+8]&i,31),d[3]=c(d[3],1)^e+2*f+s[4*a+9]&i,e=b(d[2]),f=g(d[3]),d[0]=c(d[0]^e+f+s[4*a+10]&i,31),d[1]=c(d[1],1)^e+2*f+s[4*a+11]&i}function j(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2],1)^e+f+s[4*a+10]&i,d[3]=c(d[3]^e+2*f+s[4*a+11]&i,31),e=b(d[2]),f=g(d[3]),d[0]=c(d[0],1)^e+f+s[4*a+8]&i,d[1]=c(d[1]^e+2*f+s[4*a+9]&i,31)}function k(){s=[],t=[[],[],[],[]]}function l(a,b){p=a,q=b;for(var c=[d(p,q)^s[0],d(p,q+4)^s[1],d(p,q+8)^s[2],d(p,q+12)^s[3]],f=0;8>f;f++)h(f,c);return e(p,q,c[2]^s[4]),e(p,q+4,c[3]^s[5]),e(p,q+8,c[0]^s[6]),e(p,q+12,c[1]^s[7]),q+=16,p}function m(a,b){p=a,q=b;for(var c=[d(p,q)^s[4],d(p,q+4)^s[5],d(p,q+8)^s[6],d(p,q+12)^s[7]],f=7;f>=0;f--)j(f,c);e(p,q,c[2]^s[0]),e(p,q+4,c[3]^s[1]),e(p,q+8,c[0]^s[2]),e(p,q+12,c[1]^s[3]),q+=16}function n(){return p}var o=null,p=null,q=-1,r=null;r="twofish";var s=[],t=[[],[],[],[]];return{name:"twofish",blocksize:16,open:a,close:k,encrypt:l,decrypt:m,finalize:n}}function h(a){this.tf=g(),this.tf.open(j.str2bin(a),0),this.encrypt=function(a){return this.tf.encrypt([].concat(a),0)}}var i=4294967295,j=a("../../util");b.exports=h,b.exports.keySize=h.prototype.keySize=32,b.exports.blockSize=h.prototype.blockSize=16},{"../../util":56}],11:[function(a,b){var c=a("./random.js"),d=a("./cipher"),e=a("./public_key"),f=a("../type/mpi.js");b.exports={publicKeyEncrypt:function(a,b,c){var d=function(){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":var d=new e.rsa,f=b[0].toBigInteger(),g=b[1].toBigInteger(),h=c.toBigInteger();return[d.encrypt(h,g,f)];case"elgamal":var i=new e.elgamal,j=b[0].toBigInteger(),k=b[1].toBigInteger(),l=b[2].toBigInteger(),h=c.toBigInteger();return i.encrypt(h,k,j,l);default:return[]}}();return d.map(function(a){var b=new f;return b.fromBigInteger(a),b})},publicKeyDecrypt:function(a,b,c){var d=function(){switch(a){case"rsa_encrypt_sign":case"rsa_encrypt":var d=new e.rsa,f=b[2].toBigInteger(),g=b[3].toBigInteger(),h=b[4].toBigInteger(),i=b[5].toBigInteger(),j=c[0].toBigInteger();return d.decrypt(j,f,g,h,i);case"elgamal":var k=new e.elgamal,l=b[3].toBigInteger(),m=c[0].toBigInteger(),n=c[1].toBigInteger(),g=b[0].toBigInteger();return k.decrypt(m,n,g,l);default:return null}}(),g=new f;return g.fromBigInteger(d),g},getPrivateMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 4;case"elgamal":return 1;case"dsa":return 1;default:throw new Error("Unknown algorithm")}},getPublicMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 2;case"elgamal":return 3;case"dsa":return 4;default:throw new Error("Unknown algorithm.")}},generateMpi:function(a,b){var c=function(){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":var c=new e.rsa,d=c.generate(b,"10001"),f=[];return f.push(d.n),f.push(d.ee),f.push(d.d),f.push(d.p),f.push(d.q),f.push(d.u),f;default:throw new Error("Unsupported algorithm for key generation.")}}();return c.map(function(a){var b=new f;return b.fromBigInteger(a),b})},getPrefixRandom:function(a){return c.getRandomBytes(d[a].blockSize)},generateSessionKey:function(a){return c.getRandomBytes(d[a].keySize)}}},{"../type/mpi.js":54,"./cipher":9,"./public_key":20,"./random.js":23}],12:[function(a,b){var c=a("./sha.js");b.exports={md5:a("./md5.js"),sha1:c.sha1,sha256:c.sha256,sha224:c.sha224,sha384:c.sha384,sha512:c.sha512,ripemd:a("./ripe-md.js"),digest:function(a,b){switch(a){case 1:return this.md5(b);case 2:return this.sha1(b);case 3:return this.ripemd(b);case 8:return this.sha256(b);case 9:return this.sha384(b);case 10:return this.sha512(b);case 11:return this.sha224(b);default:throw new Error("Invalid hash function.")}},getHashByteLength:function(a){switch(a){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw new Error("Invalid hash algorithm.")}}}},{"./md5.js":13,"./ripe-md.js":14,"./sha.js":15}],13:[function(a,b){function c(a){var b=n(a),c=p.hex2bin(b);return c}function d(a,b){var c=a[0],d=a[1],e=a[2],j=a[3];c=f(c,d,e,j,b[0],7,-680876936),j=f(j,c,d,e,b[1],12,-389564586),e=f(e,j,c,d,b[2],17,606105819),d=f(d,e,j,c,b[3],22,-1044525330),c=f(c,d,e,j,b[4],7,-176418897),j=f(j,c,d,e,b[5],12,1200080426),e=f(e,j,c,d,b[6],17,-1473231341),d=f(d,e,j,c,b[7],22,-45705983),c=f(c,d,e,j,b[8],7,1770035416),j=f(j,c,d,e,b[9],12,-1958414417),e=f(e,j,c,d,b[10],17,-42063),d=f(d,e,j,c,b[11],22,-1990404162),c=f(c,d,e,j,b[12],7,1804603682),j=f(j,c,d,e,b[13],12,-40341101),e=f(e,j,c,d,b[14],17,-1502002290),d=f(d,e,j,c,b[15],22,1236535329),c=g(c,d,e,j,b[1],5,-165796510),j=g(j,c,d,e,b[6],9,-1069501632),e=g(e,j,c,d,b[11],14,643717713),d=g(d,e,j,c,b[0],20,-373897302),c=g(c,d,e,j,b[5],5,-701558691),j=g(j,c,d,e,b[10],9,38016083),e=g(e,j,c,d,b[15],14,-660478335),d=g(d,e,j,c,b[4],20,-405537848),c=g(c,d,e,j,b[9],5,568446438),j=g(j,c,d,e,b[14],9,-1019803690),e=g(e,j,c,d,b[3],14,-187363961),d=g(d,e,j,c,b[8],20,1163531501),c=g(c,d,e,j,b[13],5,-1444681467),j=g(j,c,d,e,b[2],9,-51403784),e=g(e,j,c,d,b[7],14,1735328473),d=g(d,e,j,c,b[12],20,-1926607734),c=h(c,d,e,j,b[5],4,-378558),j=h(j,c,d,e,b[8],11,-2022574463),e=h(e,j,c,d,b[11],16,1839030562),d=h(d,e,j,c,b[14],23,-35309556),c=h(c,d,e,j,b[1],4,-1530992060),j=h(j,c,d,e,b[4],11,1272893353),e=h(e,j,c,d,b[7],16,-155497632),d=h(d,e,j,c,b[10],23,-1094730640),c=h(c,d,e,j,b[13],4,681279174),j=h(j,c,d,e,b[0],11,-358537222),e=h(e,j,c,d,b[3],16,-722521979),d=h(d,e,j,c,b[6],23,76029189),c=h(c,d,e,j,b[9],4,-640364487),j=h(j,c,d,e,b[12],11,-421815835),e=h(e,j,c,d,b[15],16,530742520),d=h(d,e,j,c,b[2],23,-995338651),c=i(c,d,e,j,b[0],6,-198630844),j=i(j,c,d,e,b[7],10,1126891415),e=i(e,j,c,d,b[14],15,-1416354905),d=i(d,e,j,c,b[5],21,-57434055),c=i(c,d,e,j,b[12],6,1700485571),j=i(j,c,d,e,b[3],10,-1894986606),e=i(e,j,c,d,b[10],15,-1051523),d=i(d,e,j,c,b[1],21,-2054922799),c=i(c,d,e,j,b[8],6,1873313359),j=i(j,c,d,e,b[15],10,-30611744),e=i(e,j,c,d,b[6],15,-1560198380),d=i(d,e,j,c,b[13],21,1309151649),c=i(c,d,e,j,b[4],6,-145523070),j=i(j,c,d,e,b[11],10,-1120210379),e=i(e,j,c,d,b[2],15,718787259),d=i(d,e,j,c,b[9],21,-343485551),a[0]=o(c,a[0]),a[1]=o(d,a[1]),a[2]=o(e,a[2]),a[3]=o(j,a[3])}function e(a,b,c,d,e,f){return b=o(o(b,a),o(d,f)),o(b<>>32-e,c)}function f(a,b,c,d,f,g,h){return e(b&c|~b&d,a,b,f,g,h)}function g(a,b,c,d,f,g,h){return e(b&d|c&~d,a,b,f,g,h)}function h(a,b,c,d,f,g,h){return e(b^c^d,a,b,f,g,h)}function i(a,b,c,d,f,g,h){return e(c^(b|~d),a,b,f,g,h)}function j(a){txt="";var b,c=a.length,e=[1732584193,-271733879,-1732584194,271733878];for(b=64;b<=a.length;b+=64)d(e,k(a.substring(b-64,b)));a=a.substring(b-64);var f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(b=0;b>2]|=a.charCodeAt(b)<<(b%4<<3);if(f[b>>2]|=128<<(b%4<<3),b>55)for(d(e,f),b=0;16>b;b++)f[b]=0;return f[14]=8*c,d(e,f),e}function k(a){var b,c=[];for(b=0;64>b;b+=4)c[b>>2]=a.charCodeAt(b)+(a.charCodeAt(b+1)<<8)+(a.charCodeAt(b+2)<<16)+(a.charCodeAt(b+3)<<24);return c}function l(a){for(var b="",c=0;4>c;c++)b+=q[a>>8*c+4&15]+q[a>>8*c&15];return b}function m(a){for(var b=0;b>16)+(b>>16)+(c>>16);return d<<16|65535&c}var p=a("../../util"),q="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=n("hello"),b.exports=c},{"../../util":56}],14:[function(a,b){function c(a,b){return new Number(a<>>32-b)}function d(a,b,c){return new Number(a^b^c)}function e(a,b,c){return new Number(a&b|~a&c)}function f(a,b,c){return new Number((a|~b)^c)}function g(a,b,c){return new Number(a&c|b&~c)}function h(a,b,c){return new Number(a^(b|~c))}function i(a,b,i,j,k,l,m,n){switch(n){case 0:a+=d(b,i,j)+l+0;break;case 1:a+=e(b,i,j)+l+1518500249;break;case 2:a+=f(b,i,j)+l+1859775393;break;case 3:a+=g(b,i,j)+l+2400959708;break;case 4:a+=h(b,i,j)+l+2840853838;break;case 5:a+=h(b,i,j)+l+1352829926;break;case 6:a+=g(b,i,j)+l+1548603684;break;case 7:a+=f(b,i,j)+l+1836072691;break;case 8:a+=e(b,i,j)+l+2053994217;break;case 9:a+=d(b,i,j)+l+0;break;default:document.write("Bogus round number")}a=c(a,m)+k,i=c(i,10),a&=4294967295,b&=4294967295,i&=4294967295,j&=4294967295,k&=4294967295;var o=new Array;return o[0]=a,o[1]=b,o[2]=i,o[3]=j,o[4]=k,o[5]=l,o[6]=m,o}function j(a){a[0]=1732584193,a[1]=4023233417,a[2]=2562383102,a[3]=271733878,a[4]=3285377520}function k(a,b){blockA=new Array,blockB=new Array;for(var c,d=0;5>d;d++)blockA[d]=new Number(a[d]),blockB[d]=new Number(a[d]);for(var e=0,f=0;5>f;f++)for(var d=0;16>d;d++)c=i(blockA[(e+0)%5],blockA[(e+1)%5],blockA[(e+2)%5],blockA[(e+3)%5],blockA[(e+4)%5],b[s[f][d]],r[f][d],f),blockA[(e+0)%5]=c[0],blockA[(e+1)%5]=c[1],blockA[(e+2)%5]=c[2],blockA[(e+3)%5]=c[3],blockA[(e+4)%5]=c[4],e+=4;e=0;for(var f=5;10>f;f++)for(var d=0;16>d;d++)c=i(blockB[(e+0)%5],blockB[(e+1)%5],blockB[(e+2)%5],blockB[(e+3)%5],blockB[(e+4)%5],b[s[f][d]],r[f][d],f),blockB[(e+0)%5]=c[0],blockB[(e+1)%5]=c[1],blockB[(e+2)%5]=c[2],blockB[(e+3)%5]=c[3],blockB[(e+4)%5]=c[4],e+=4;blockB[3]+=blockA[2]+a[1],a[1]=a[2]+blockA[3]+blockB[4],a[2]=a[3]+blockA[4]+blockB[0],a[3]=a[4]+blockA[0]+blockB[1],a[4]=a[0]+blockA[1]+blockB[2],a[0]=blockB[3]}function l(a){for(var b=0;16>b;b++)a[b]=0}function m(a,b,c,d){var e=new Array(16);l(e);for(var f=0,g=0;(63&c)>g;g++)e[g>>>2]^=(255&b.charCodeAt(f++))<<8*(3&g);if(e[c>>>2&15]^=1<<8*(3&c)+7,(63&c)>55){k(a,e);var e=new Array(16);l(e)}e[14]=c<<3,e[15]=c>>>29|d<<3,k(a,e)}function n(a){var b=(255&a.charCodeAt(3))<<24;return b|=(255&a.charCodeAt(2))<<16,b|=(255&a.charCodeAt(1))<<8,b|=255&a.charCodeAt(0)}function o(a){var b,c,d=new Array(q/32),e=new Array(q/8);j(d),b=a.length;var f=new Array(16);l(f);for(var g=0,c=b;c>63;c-=64){for(var h=0;16>h;h++)f[h]=n(a.substr(g,4)),g+=4;k(d,f)}m(d,a.substr(g),b,0);for(var h=0;q/8>h;h+=4)e[h]=255&d[h>>>2],e[h+1]=d[h>>>2]>>>8&255,e[h+2]=d[h>>>2]>>>16&255,e[h+3]=d[h>>>2]>>>24&255;return e}function p(a){for(var b=o(a),c="",d=0;q/8>d;d++)c+=String.fromCharCode(b[d]);return c}var q=160,r=(new Array,[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]]),s=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]];b.exports=p},{}],15:[function(a,b){var c=function(){var a=8,b="",c=0,d=function(a,b){this.highOrder=a,this.lowOrder=b},e=function(b){var c,d=[],e=(1<c;c+=a)d[c>>5]|=(b.charCodeAt(c/a)&e)<<32-a-c%32;return d},f=function(a){var b,c,d=[],e=a.length;for(b=0;e>b;b+=2){if(c=parseInt(a.substr(b,2),16),isNaN(c))return"INVALID HEX STRING";d[b>>3]|=c<<24-4*(b%8)}return d},g=function(a){var b,d,e=c?"0123456789ABCDEF":"0123456789abcdef",f="",g=4*a.length;for(b=0;g>b;b+=1)d=a[b>>2]>>8*(3-b%4),f+=e.charAt(d>>4&15)+e.charAt(15&d);return f},h=function(a){var c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g="",h=4*a.length;for(c=0;h>c;c+=3)for(e=(a[c>>2]>>8*(3-c%4)&255)<<16|(a[c+1>>2]>>8*(3-(c+1)%4)&255)<<8|a[c+2>>2]>>8*(3-(c+2)%4)&255,d=0;4>d;d+=1)g+=8*c+6*d<=32*a.length?f.charAt(e>>6*(3-d)&63):b;return g},i=function(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b},j=function(a,b){return a<>>32-b},k=function(a,b){return a>>>b|a<<32-b},l=function(a,b){return 32>=b?new d(a.highOrder>>>b|a.lowOrder<<32-b,a.lowOrder>>>b|a.highOrder<<32-b):new d(a.lowOrder>>>b|a.highOrder<<32-b,a.highOrder>>>b|a.lowOrder<<32-b)},m=function(a,b){return a>>>b},n=function(a,b){return 32>=b?new d(a.highOrder>>>b,a.lowOrder>>>b|a.highOrder<<32-b):new d(0,a.highOrder<<32-b)},o=function(a,b,c){return a^b^c},p=function(a,b,c){return a&b^~a&c},q=function(a,b,c){return new d(a.highOrder&b.highOrder^~a.highOrder&c.highOrder,a.lowOrder&b.lowOrder^~a.lowOrder&c.lowOrder)},r=function(a,b,c){return a&b^a&c^b&c},s=function(a,b,c){return new d(a.highOrder&b.highOrder^a.highOrder&c.highOrder^b.highOrder&c.highOrder,a.lowOrder&b.lowOrder^a.lowOrder&c.lowOrder^b.lowOrder&c.lowOrder)},t=function(a){return k(a,2)^k(a,13)^k(a,22)},u=function(a){var b=l(a,28),c=l(a,34),e=l(a,39);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},v=function(a){return k(a,6)^k(a,11)^k(a,25)},w=function(a){var b=l(a,14),c=l(a,18),e=l(a,41);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},x=function(a){return k(a,7)^k(a,18)^m(a,3)},y=function(a){var b=l(a,1),c=l(a,8),e=n(a,7);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},z=function(a){return k(a,17)^k(a,19)^m(a,10)},A=function(a){var b=l(a,19),c=l(a,61),e=n(a,6);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},B=function(a,b){var c=(65535&a)+(65535&b),d=(a>>>16)+(b>>>16)+(c>>>16);return(65535&d)<<16|65535&c},C=function(a,b,c,d){var e=(65535&a)+(65535&b)+(65535&c)+(65535&d),f=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16);return(65535&f)<<16|65535&e},D=function(a,b,c,d,e){var f=(65535&a)+(65535&b)+(65535&c)+(65535&d)+(65535&e),g=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return(65535&g)<<16|65535&f},E=function(a,b){var c,e,f,g;return c=(65535&a.lowOrder)+(65535&b.lowOrder),e=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c>>>16),f=(65535&e)<<16|65535&c,c=(65535&a.highOrder)+(65535&b.highOrder)+(e>>>16),e=(a.highOrder>>>16)+(b.highOrder>>>16)+(c>>>16),g=(65535&e)<<16|65535&c,new d(g,f)},F=function(a,b,c,e){var f,g,h,i;return f=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder),g=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16),h=(65535&g)<<16|65535&f,f=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(g>>>16),g=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16),i=(65535&g)<<16|65535&f,new d(i,h)},G=function(a,b,c,e,f){var g,h,i,j;return g=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder)+(65535&f.lowOrder),h=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16),i=(65535&h)<<16|65535&g,g=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(65535&f.highOrder)+(h>>>16),h=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16),j=(65535&h)<<16|65535&g,new d(j,i)},H=function(a,b){var c,d,e,f,g,h,i,k,l,m=[],n=p,q=o,s=r,t=j,u=B,v=D,w=[1732584193,4023233417,2562383102,271733878,3285377520],x=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(a[b>>5]|=128<<24-b%32,a[(b+65>>9<<4)+15]=b,l=a.length,i=0;l>i;i+=16){for(c=w[0],d=w[1],e=w[2],f=w[3],g=w[4],k=0;80>k;k+=1)m[k]=16>k?a[k+i]:t(m[k-3]^m[k-8]^m[k-14]^m[k-16],1),h=20>k?v(t(c,5),n(d,e,f),g,x[k],m[k]):40>k?v(t(c,5),q(d,e,f),g,x[k],m[k]):60>k?v(t(c,5),s(d,e,f),g,x[k],m[k]):v(t(c,5),q(d,e,f),g,x[k],m[k]),g=f,f=e,e=t(d,30),d=c,c=h;w[0]=u(c,w[0]),w[1]=u(d,w[1]),w[2]=u(e,w[2]),w[3]=u(f,w[3]),w[4]=u(g,w[4])}return w},I=function(a,b,c){var e,f,g,h,i,j,k,l,m,n,o,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z=[];for("SHA-224"===c||"SHA-256"===c?(H=64,I=(b+65>>9<<4)+15,L=16,M=1,W=Number,N=B,O=C,P=D,Q=x,R=z,S=t,T=v,V=r,U=p,X=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],o="SHA-224"===c?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===c||"SHA-512"===c)&&(H=80,I=(b+128>>10<<5)+31,L=32,M=2,W=d,N=E,O=F,P=G,Q=y,R=A,S=u,T=w,V=s,U=q,X=[new W(1116352408,3609767458),new W(1899447441,602891725),new W(3049323471,3964484399),new W(3921009573,2173295548),new W(961987163,4081628472),new W(1508970993,3053834265),new W(2453635748,2937671579),new W(2870763221,3664609560),new W(3624381080,2734883394),new W(310598401,1164996542),new W(607225278,1323610764),new W(1426881987,3590304994),new W(1925078388,4068182383),new W(2162078206,991336113),new W(2614888103,633803317),new W(3248222580,3479774868),new W(3835390401,2666613458),new W(4022224774,944711139),new W(264347078,2341262773),new W(604807628,2007800933),new W(770255983,1495990901),new W(1249150122,1856431235),new W(1555081692,3175218132),new W(1996064986,2198950837),new W(2554220882,3999719339),new W(2821834349,766784016),new W(2952996808,2566594879),new W(3210313671,3203337956),new W(3336571891,1034457026),new W(3584528711,2466948901),new W(113926993,3758326383),new W(338241895,168717936),new W(666307205,1188179964),new W(773529912,1546045734),new W(1294757372,1522805485),new W(1396182291,2643833823),new W(1695183700,2343527390),new W(1986661051,1014477480),new W(2177026350,1206759142),new W(2456956037,344077627),new W(2730485921,1290863460),new W(2820302411,3158454273),new W(3259730800,3505952657),new W(3345764771,106217008),new W(3516065817,3606008344),new W(3600352804,1432725776),new W(4094571909,1467031594),new W(275423344,851169720),new W(430227734,3100823752),new W(506948616,1363258195),new W(659060556,3750685593),new W(883997877,3785050280),new W(958139571,3318307427),new W(1322822218,3812723403),new W(1537002063,2003034995),new W(1747873779,3602036899),new W(1955562222,1575990012),new W(2024104815,1125592928),new W(2227730452,2716904306),new W(2361852424,442776044),new W(2428436474,593698344),new W(2756734187,3733110249),new W(3204031479,2999351573),new W(3329325298,3815920427),new W(3391569614,3928383900),new W(3515267271,566280711),new W(3940187606,3454069534),new W(4118630271,4000239992),new W(116418474,1914138554),new W(174292421,2731055270),new W(289380356,3203993006),new W(460393269,320620315),new W(685471733,587496836),new W(852142971,1086792851),new W(1017036298,365543100),new W(1126000580,2618297676),new W(1288033470,3409855158),new W(1501505948,4234509866),new W(1607167915,987167468),new W(1816402316,1246189591)],o="SHA-384"===c?[new W(3418070365,3238371032),new W(1654270250,914150663),new W(2438529370,812702999),new W(355462360,4144912697),new W(1731405415,4290775857),new W(41048885895,1750603025),new W(3675008525,1694076839),new W(1203062813,3204075428)]:[new W(1779033703,4089235720),new W(3144134277,2227873595),new W(1013904242,4271175723),new W(2773480762,1595750129),new W(1359893119,2917565137),new W(2600822924,725511199),new W(528734635,4215389547),new W(1541459225,327033209)]),a[b>>5]|=128<<24-b%32,a[I]=b,Y=a.length,J=0;Y>J;J+=L){for(e=o[0],f=o[1],g=o[2],h=o[3],i=o[4],j=o[5],k=o[6],l=o[7],K=0;H>K;K+=1)Z[K]=16>K?new W(a[K*M+J],a[K*M+J+1]):O(R(Z[K-2]),Z[K-7],Q(Z[K-15]),Z[K-16]),m=P(l,T(i),U(i,j,k),X[K],Z[K]),n=N(S(e),V(e,f,g)),l=k,k=j,j=i,i=N(h,m),h=g,g=f,f=e,e=N(m,n);o[0]=N(e,o[0]),o[1]=N(f,o[1]),o[2]=N(g,o[2]),o[3]=N(h,o[3]),o[4]=N(i,o[4]),o[5]=N(j,o[5]),o[6]=N(k,o[6]),o[7]=N(l,o[7])}switch(c){case"SHA-224":return[o[0],o[1],o[2],o[3],o[4],o[5],o[6]];case"SHA-256":return o;case"SHA-384":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder];case"SHA-512":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder,o[6].highOrder,o[6].lowOrder,o[7].highOrder,o[7].lowOrder];default:return[]}},J=function(b,c){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===c){if(0!==b.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*b.length,this.strToHash=f(b)}else{if("ASCII"!==c&&"undefined"!=typeof c)return"UNKNOWN TEXT INPUT TYPE";this.strBinLen=b.length*a,this.strToHash=e(b)}};return J.prototype={getHash:function(a,b){var c=null,d=this.strToHash.slice();switch(b){case"HEX":c=g;break;case"B64":c=h;break;case"ASCII":c=i;break;default:return"FORMAT NOT RECOGNIZED"}switch(a){case"SHA-1":return null===this.sha1&&(this.sha1=H(d,this.strBinLen)),c(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=I(d,this.strBinLen,a)),c(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=I(d,this.strBinLen,a)),c(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=I(d,this.strBinLen,a)),c(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=I(d,this.strBinLen,a)),c(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(b,c,d,j){var k,l,m,n,o,p,q,r,s,t=[],u=[];switch(j){case"HEX":k=g;break;case"B64":k=h;break;case"ASCII":k=i;break;default:return"FORMAT NOT RECOGNIZED"}switch(d){case"SHA-1":m=64,s=160;break;case"SHA-224":m=64,s=224;break;case"SHA-256":m=64,s=256;break;case"SHA-384":m=128,s=384;break;case"SHA-512":m=128,s=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===c){if(0!==b.length%2)return"KEY MUST BE IN BYTE INCREMENTS";l=f(b),r=4*b.length}else{if("ASCII"!==c)return"UNKNOWN KEY INPUT TYPE";l=e(b),r=b.length*a}for(n=8*m,q=m/4-1,r/8>m?(l="SHA-1"===d?H(l,r):I(l,r,d),l[q]&=4294967040):m>r/8&&(l[q]&=4294967040),o=0;q>=o;o+=1)t[o]=909522486^l[o],u[o]=1549556828^l[o];return"SHA-1"===d?(p=H(t.concat(this.strToHash),n+this.strBinLen),p=H(u.concat(p),n+s)):(p=I(t.concat(this.strToHash),n+this.strBinLen,d),p=I(u.concat(p),n+s,d)),k(p)}},J}();b.exports={sha1:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-1","ASCII")},sha224:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-224","ASCII")},sha256:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-256","ASCII")},sha384:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-384","ASCII")},sha512:function(a){var b=new c(a,"ASCII"); return b.getHash("SHA-512","ASCII")}}},{}],16:[function(a,b){b.exports={cipher:a("./cipher"),hash:a("./hash"),cfb:a("./cfb.js"),publicKey:a("./public_key"),signature:a("./signature.js"),random:a("./random.js"),pkcs1:a("./pkcs1.js")};var c=a("./crypto.js");for(var d in c)b.exports[d]=c[d]},{"./cfb.js":4,"./cipher":9,"./crypto.js":11,"./hash":12,"./pkcs1.js":17,"./public_key":20,"./random.js":23,"./signature.js":24}],17:[function(a,b){hash_headers=new Array,hash_headers[1]=[48,32,48,12,6,8,42,134,72,134,247,13,2,5,5,0,4,16],hash_headers[3]=[48,33,48,9,6,5,43,36,3,2,1,5,0,4,20],hash_headers[2]=[48,33,48,9,6,5,43,14,3,2,26,5,0,4,20],hash_headers[8]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,1,5,0,4,32],hash_headers[9]=[48,65,48,13,6,9,96,134,72,1,101,3,4,2,2,5,0,4,48],hash_headers[10]=[48,81,48,13,6,9,96,134,72,1,101,3,4,2,3,5,0,4,64],hash_headers[11]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,4,5,0,4,28];var c=(a("./crypto.js"),a("./random.js")),d=a("../util"),e=a("./public_key/jsbn.js"),f=a("./hash");b.exports={eme:{encode:function(a,b){if(a.length>b-11)return-1;var d="";d+=String.fromCharCode(0),d+=String.fromCharCode(2);for(var e=0;ec;)c++;return a.substring(c+1,a.length)}},emsa:{encode:function(a,b,c){var g="";g+=String.fromCharCode(0),g+=String.fromCharCode(1);for(var h=0;h11&&10!=b&&8>b?2:b;case 28:return b>11&&8>b?11:b;case 32:return b>10&&8>b?8:b;default:return g.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}}function c(a,b,c,e,h,i,j,k){var l=g.getLeftNBits(f.digest(a,e),i.bitLength()),m=new d(g.hexstrdump(l),16);if(d.ZERO.compareTo(b)>0||b.compareTo(i)>0||d.ZERO.compareTo(c)>0||c.compareTo(i)>0)return g.print_debug("invalid DSA Signature"),null;var n=c.modInverse(i),o=m.multiply(n).mod(i),p=b.multiply(n).mod(i);return j.modPow(o,h).multiply(k.modPow(p,h)).mod(h).mod(i)}this.select_hash_algorithm=b,this.sign=a,this.verify=c}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../hash"),g=a("../../util");b.exports=c},{"../../util":56,"../hash":12,"../random.js":23,"./jsbn.js":21}],19:[function(a,b){function c(){function a(a,b,c,f){var g=d.ONE.add(d.ONE),h=c.subtract(g),i=e.getRandomBigIntegerInRange(g,h);i=i.mod(h).add(d.ONE);var j=[];return j[0]=b.modPow(i,c),j[1]=f.modPow(i,c).multiply(a).mod(c),j}function b(a,b,c,d){return f.print_debug("Elgamal Decrypt:\nc1:"+f.hexstrdump(a.toMPI())+"\nc2:"+f.hexstrdump(b.toMPI())+"\np:"+f.hexstrdump(c.toMPI())+"\nx:"+f.hexstrdump(d.toMPI())),a.modPow(d,c).modInverse(c).multiply(b).mod(c)}this.encrypt=a,this.decrypt=b}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../../util");b.exports=c},{"../../util":56,"../random.js":23,"./jsbn.js":21}],20:[function(a,b){b.exports={rsa:a("./rsa.js"),elgamal:a("./elgamal.js"),dsa:a("./dsa.js")}},{"./dsa.js":18,"./elgamal.js":19,"./rsa.js":22}],21:[function(a,b){function c(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function d(){return new c(null)}function e(a,b,c,d,e,f){for(;--f>=0;){var g=b*this[a++]+c[d]+e;e=Math.floor(g/67108864),c[d++]=67108863&g}return e}function f(a){return ec.charAt(a)}function g(a,b){var c=fc[a.charCodeAt(b)];return null==c?-1:c}function h(a){for(var b=this.t-1;b>=0;--b)a[b]=this[b];a.t=this.t,a.s=this.s}function i(a){this.t=1,this.s=0>a?-1:0,a>0?this[0]=a:-1>a?this[0]=a+DV:this.t=0}function j(a){var b=d();return b.fromInt(a),b}function k(a,b){var d;if(16==b)d=4;else if(8==b)d=3;else if(256==b)d=8;else if(2==b)d=1;else if(32==b)d=5;else{if(4!=b)return this.fromRadix(a,b),void 0;d=2}this.t=0,this.s=0;for(var e=a.length,f=!1,h=0;--e>=0;){var i=8==d?255&a[e]:g(a,e);0>i?"-"==a.charAt(e)&&(f=!0):(f=!1,0==h?this[this.t++]=i:h+d>this.DB?(this[this.t-1]|=(i&(1<>this.DB-h):this[this.t-1]|=i<=this.DB&&(h-=this.DB))}8==d&&0!=(128&a[0])&&(this.s=-1,h>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==a;)--this.t}function m(a){if(this.s<0)return"-"+this.negate().toString(a);var b;if(16==a)b=4;else if(8==a)b=3;else if(2==a)b=1;else if(32==a)b=5;else{if(4!=a)return this.toRadix(a);b=2}var c,d=(1<0)for(i>i)>0&&(e=!0,g=f(c));h>=0;)b>i?(c=(this[h]&(1<>(i+=this.DB-b)):(c=this[h]>>(i-=b)&d,0>=i&&(i+=this.DB,--h)),c>0&&(e=!0),e&&(g+=f(c));return e?g:"0"}function n(){var a=d();return c.ZERO.subTo(this,a),a}function o(){return this.s<0?this.negate():this}function p(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t;if(b=c-a.t,0!=b)return b;for(;--c>=0;)if(0!=(b=this[c]-a[c]))return b;return 0}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function r(){return this.t<=0?0:this.DB*(this.t-1)+q(this[this.t-1]^this.s&this.DM)}function s(a,b){var c;for(c=this.t-1;c>=0;--c)b[c+a]=this[c];for(c=a-1;c>=0;--c)b[c]=0;b.t=this.t+a,b.s=this.s}function t(a,b){for(var c=a;c=0;--c)b[c+g+1]=this[c]>>e|h,h=(this[c]&f)<=0;--c)b[c]=0;b[g]=h,b.t=this.t+g+1,b.s=this.s,b.clamp()}function v(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)return b.t=0,void 0;var d=a%this.DB,e=this.DB-d,f=(1<>d;for(var g=c+1;g>d;d>0&&(b[this.t-c-1]|=(this.s&f)<c;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0,-1>d?b[c++]=this.DV+d:d>0&&(b[c++]=d),b.t=c,b.clamp()}function x(a,b){var d=this.abs(),e=a.abs(),f=d.t;for(b.t=f+e.t;--f>=0;)b[f]=0;for(f=0;f=0;)a[c]=0;for(c=0;c=b.DV&&(a[c+b.t]-=b.DV,a[c+b.t+1]=1)}a.t>0&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1)),a.s=0,a.clamp()}function z(a,b,e){var f=a.abs();if(!(f.t<=0)){var g=this.abs();if(g.t0?(f.lShiftTo(k,h),g.lShiftTo(k,e)):(f.copyTo(h),g.copyTo(e));var l=h.t,m=h[l-1];if(0!=m){var n=m*(1<1?h[l-2]>>this.F2:0),o=this.FV/n,p=(1<=0&&(e[e.t++]=1,e.subTo(u,e)),c.ONE.dlShiftTo(l,u),u.subTo(h,h);h.t=0;){var v=e[--s]==m?this.DM:Math.floor(e[s]*o+(e[s-1]+r)*p);if((e[s]+=h.am(0,v,e,t,0,l))0&&e.rShiftTo(k,e),0>i&&c.ZERO.subTo(e,e)}}}function A(a){var b=d();return this.abs().divRemTo(a,null,b),this.s<0&&b.compareTo(c.ZERO)>0&&a.subTo(b,b),b}function B(a){this.m=a}function C(a){return a.s<0||a.compareTo(this.m)>=0?a.mod(this.m):a}function D(a){return a}function E(a){a.divRemTo(this.m,null,a)}function F(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function G(a,b){a.squareTo(b),this.reduce(b)}function H(){if(this.t<1)return 0;var a=this[0];if(0==(1&a))return 0;var b=3&a;return b=b*(2-(15&a)*b)&15,b=b*(2-(255&a)*b)&255,b=b*(2-((65535&a)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV,b>0?this.DV-b:-b}function I(a){this.m=a,this.mp=a.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(b,b),b}function K(a){var b=d();return a.copyTo(b),this.reduce(b),b}function L(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b>15)*this.mpl&this.um)<<15)&a.DM;for(c=b+this.m.t,a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp(),a.drShiftTo(this.m.t,a),a.compareTo(this.m)>=0&&a.subTo(this.m,a)}function M(a,b){a.squareTo(b),this.reduce(b)}function N(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function O(){return 0==(this.t>0?1&this[0]:this.s)}function P(a,b){if(a>4294967295||1>a)return c.ONE;var e=d(),f=d(),g=b.convert(this),h=q(a)-1;for(g.copyTo(e);--h>=0;)if(b.sqrTo(e,f),(a&1<0)b.mulTo(f,g,e);else{var i=e;e=f,f=i}return b.revert(e)}function Q(a,b){var c;return c=256>a||b.isEven()?new B(b):new I(b),this.exp(a,c)}function R(){var a=d();return this.copyTo(a),a}function S(){if(this.s<0){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function U(){return 0==this.t?this.s:this[0]<<16>>16}function V(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function W(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1}function X(a){if(null==a&&(a=10),0==this.signum()||2>a||a>36)return"0";var b=this.chunkSize(a),c=Math.pow(a,b),e=j(c),f=d(),g=d(),h="";for(this.divRemTo(e,f,g);f.signum()>0;)h=(c+g.intValue()).toString(a).substr(1)+h,f.divRemTo(e,f,g);return g.intValue().toString(a)+h}function Y(a,b){this.fromInt(0),null==b&&(b=10);for(var d=this.chunkSize(b),e=Math.pow(b,d),f=!1,h=0,i=0,j=0;jk?"-"==a.charAt(j)&&0==this.signum()&&(f=!0):(i=b*i+k,++h>=d&&(this.dMultiply(e),this.dAddOffset(i,0),h=0,i=0))}h>0&&(this.dMultiply(Math.pow(b,h)),this.dAddOffset(i,0)),f&&c.ZERO.subTo(this,this)}function Z(a,b,d){if("number"==typeof b)if(2>a)this.fromInt(1);else for(this.fromNumber(a,d),this.testBit(a-1)||this.bitwiseTo(c.ONE.shiftLeft(a-1),fb,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(c.ONE.shiftLeft(a-1),this);else{var e=new Array,f=7&a;e.length=(a>>3)+1,b.nextBytes(e),f>0?e[0]&=(1<0)for(d>d)!=(this.s&this.DM)>>d&&(b[e++]=c|this.s<=0;)8>d?(c=(this[a]&(1<>(d+=this.DB-8)):(c=this[a]>>(d-=8)&255,0>=d&&(d+=this.DB,--a)),(e>0||c!=this.s)&&(b[e++]=c);return b}function _(a){return 0==this.compareTo(a)}function ab(a){return this.compareTo(a)<0?this:a}function bb(a){return this.compareTo(a)>0?this:a}function cb(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;f>d;++d)c[d]=b(this[d],a[d]);if(a.ta?this.rShiftTo(-a,b):this.lShiftTo(a,b),b}function nb(a){var b=d();return 0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b),b}function ob(a){if(0==a)return-1;var b=0;return 0==(65535&a)&&(a>>=16,b+=16),0==(255&a)&&(a>>=8,b+=8),0==(15&a)&&(a>>=4,b+=4),0==(3&a)&&(a>>=2,b+=2),0==(1&a)&&++b,b}function pb(){for(var a=0;a=this.t?0!=this.s:0!=(this[b]&1<c;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=a.s}b.s=0>d?-1:0,d>0?b[c++]=d:-1>d&&(b[c++]=this.DV+d),b.t=c,b.clamp()}function yb(a){var b=d();return this.addTo(a,b),b}function zb(a){var b=d();return this.subTo(a,b),b}function Ab(a){var b=d();return this.multiplyTo(a,b),b}function Bb(){var a=d();return this.squareTo(a),a}function Cb(a){var b=d();return this.divRemTo(a,b,null),b}function Db(a){var b=d();return this.divRemTo(a,null,b),b}function Eb(a){var b=d(),c=d();return this.divRemTo(a,b,c),new Array(b,c)}function Fb(a){this[this.t]=this.am(0,a-1,this,0,0,this.t),++this.t,this.clamp()}function Gb(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function Hb(){}function Ib(a){return a}function Jb(a,b,c){a.multiplyTo(b,c)}function Kb(a,b){a.squareTo(b)}function Lb(a){return this.exp(a,new Hb)}function Mb(a,b,c){var d=Math.min(this.t+a.t,b);for(c.s=0,c.t=d;d>0;)c[--d]=0;var e;for(e=c.t-this.t;e>d;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);e>d;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function Nb(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;--d>=0;)c[d]=0;for(d=Math.max(b-this.t,0);d2*this.m.t)return a.mod(this.m);if(a.compareTo(this.m)<0)return a;var b=d();return a.copyTo(b),this.reduce(b),b}function Qb(a){return a}function Rb(a){for(a.drShiftTo(this.m.t-1,this.r2),a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);a.compareTo(this.r2)<0;)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);a.compareTo(this.m)>=0;)a.subTo(this.m,a)}function Sb(a,b){a.squareTo(b),this.reduce(b)}function Tb(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function Ub(a,b){var c,e,f=a.bitLength(),g=j(1);if(0>=f)return g;c=18>f?1:48>f?3:144>f?4:768>f?5:6,e=8>f?new B(b):b.isEven()?new Ob(b):new I(b);var h=new Array,i=3,k=c-1,l=(1<1){var m=d();for(e.sqrTo(h[1],m);l>=i;)h[i]=d(),e.mulTo(m,h[i-2],h[i]),i+=2}var n,o,p=a.t-1,r=!0,s=d();for(f=q(a[p])-1;p>=0;){for(f>=k?n=a[p]>>f-k&l:(n=(a[p]&(1<0&&(n|=a[p-1]>>this.DB+f-k)),i=c;0==(1&n);)n>>=1,--i;if((f-=i)<0&&(f+=this.DB,--p),r)h[n].copyTo(g),r=!1;else{for(;i>1;)e.sqrTo(g,s),e.sqrTo(s,g),i-=2;i>0?e.sqrTo(g,s):(o=g,g=s,s=o),e.mulTo(s,h[n],g)}for(;p>=0&&0==(a[p]&1<f)return b;for(f>e&&(f=e),f>0&&(b.rShiftTo(f,b),c.rShiftTo(f,c));b.signum()>0;)(e=b.getLowestSetBit())>0&&b.rShiftTo(e,b),(e=c.getLowestSetBit())>0&&c.rShiftTo(e,c),b.compareTo(c)>=0?(b.subTo(c,b),b.rShiftTo(1,b)):(c.subTo(b,c),c.rShiftTo(1,c));return f>0&&c.lShiftTo(f,c),c}function Wb(a){if(0>=a)return 0;var b=this.DV%a,c=this.s<0?a-1:0;if(this.t>0)if(0==b)c=this[0]%a;else for(var d=this.t-1;d>=0;--d)c=(b*c+this[d])%a;return c}function Xb(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return c.ZERO;for(var d=a.clone(),e=this.clone(),f=j(1),g=j(0),h=j(0),i=j(1);0!=d.signum();){for(;d.isEven();)d.rShiftTo(1,d),b?(f.isEven()&&g.isEven()||(f.addTo(this,f),g.subTo(a,g)),f.rShiftTo(1,f)):g.isEven()||g.subTo(a,g),g.rShiftTo(1,g);for(;e.isEven();)e.rShiftTo(1,e),b?(h.isEven()&&i.isEven()||(h.addTo(this,h),i.subTo(a,i)),h.rShiftTo(1,h)):i.isEven()||i.subTo(a,i),i.rShiftTo(1,i);d.compareTo(e)>=0?(d.subTo(e,d),b&&f.subTo(h,f),g.subTo(i,g)):(e.subTo(d,e),b&&h.subTo(f,h),i.subTo(g,i))}return 0!=e.compareTo(c.ONE)?c.ZERO:i.compareTo(a)>=0?i.subtract(a):i.signum()<0?(i.addTo(a,i),i.signum()<0?i.add(a):i):i}function Yb(a){var b,c=this.abs();if(1==c.t&&c[0]<=gc[gc.length-1]){for(b=0;bd;)d*=gc[e++];for(d=c.modInt(d);e>b;)if(d%gc[b++]==0)return!1}return c.millerRabin(a)}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function Zb(){var a=this.toByteArray(),b=8*(a.length-1)+q(a[0]),c="";return c+=String.fromCharCode((65280&b)>>8),c+=String.fromCharCode(255&b),c+=ac.bin2str(a)}function $b(a){var b=this.subtract(c.ONE),e=b.getLowestSetBit();if(0>=e)return!1;var f=b.shiftRight(e);a=a+1>>1,a>gc.length&&(a=gc.length);for(var g,h=d(),i=[],j=0;a>j;++j){for(;g=gc[Math.floor(Math.random()*gc.length)],-1!=i.indexOf(g););i.push(g),h.fromInt(g);var k=h.modPow(f,this);if(0!=k.compareTo(c.ONE)&&0!=k.compareTo(b)){for(var g=1;g++=dc;++dc)fc[cc++]=dc;for(cc="a".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;for(cc="A".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;B.prototype.convert=C,B.prototype.revert=D,B.prototype.reduce=E,B.prototype.mulTo=F,B.prototype.sqrTo=G,I.prototype.convert=J,I.prototype.revert=K,I.prototype.reduce=L,I.prototype.mulTo=N,I.prototype.sqrTo=M,c.prototype.copyTo=h,c.prototype.fromInt=i,c.prototype.fromString=k,c.prototype.clamp=l,c.prototype.dlShiftTo=s,c.prototype.drShiftTo=t,c.prototype.lShiftTo=u,c.prototype.rShiftTo=v,c.prototype.subTo=w,c.prototype.multiplyTo=x,c.prototype.squareTo=y,c.prototype.divRemTo=z,c.prototype.invDigit=H,c.prototype.isEven=O,c.prototype.exp=P,c.prototype.toString=m,c.prototype.negate=n,c.prototype.abs=o,c.prototype.compareTo=p,c.prototype.bitLength=r,c.prototype.mod=A,c.prototype.modPowInt=Q,c.ZERO=j(0),c.ONE=j(1),b.exports=c,Hb.prototype.convert=Ib,Hb.prototype.revert=Ib,Hb.prototype.mulTo=Jb,Hb.prototype.sqrTo=Kb,Ob.prototype.convert=Pb,Ob.prototype.revert=Qb,Ob.prototype.reduce=Rb,Ob.prototype.mulTo=Tb,Ob.prototype.sqrTo=Sb;var gc=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],hc=(1<<26)/gc[gc.length-1],c=a("./jsbn.js");c.prototype.chunkSize=V,c.prototype.toRadix=X,c.prototype.fromRadix=Y,c.prototype.fromNumber=Z,c.prototype.bitwiseTo=cb,c.prototype.changeBit=tb,c.prototype.addTo=xb,c.prototype.dMultiply=Fb,c.prototype.dAddOffset=Gb,c.prototype.multiplyLowerTo=Mb,c.prototype.multiplyUpperTo=Nb,c.prototype.modInt=Wb,c.prototype.millerRabin=$b,c.prototype.clone=R,c.prototype.intValue=S,c.prototype.byteValue=T,c.prototype.shortValue=U,c.prototype.signum=W,c.prototype.toByteArray=$,c.prototype.equals=_,c.prototype.min=ab,c.prototype.max=bb,c.prototype.and=eb,c.prototype.or=gb,c.prototype.xor=ib,c.prototype.andNot=kb,c.prototype.not=lb,c.prototype.shiftLeft=mb,c.prototype.shiftRight=nb,c.prototype.getLowestSetBit=pb,c.prototype.bitCount=rb,c.prototype.testBit=sb,c.prototype.setBit=ub,c.prototype.clearBit=vb,c.prototype.flipBit=wb,c.prototype.add=yb,c.prototype.subtract=zb,c.prototype.multiply=Ab,c.prototype.divide=Cb,c.prototype.remainder=Db,c.prototype.divideAndRemainder=Eb,c.prototype.modPow=Ub,c.prototype.modInverse=Xb,c.prototype.pow=Lb,c.prototype.gcd=Vb,c.prototype.isProbablePrime=Yb,c.prototype.toMPI=Zb,c.prototype.square=Bb},{"../../util":56,"./jsbn.js":21}],22:[function(a,b){function c(){function a(a){for(var b=0;b>1;for(d.e=parseInt(b,16),d.ee=new e(b,16);;){for(;d.p=new e(a-g,1,f),0!=d.p.subtract(e.ONE).gcd(d.ee).compareTo(e.ONE)||!d.p.isProbablePrime(10););for(;d.q=new e(g,1,f),0!=d.q.subtract(e.ONE).gcd(d.ee).compareTo(e.ONE)||!d.q.isProbablePrime(10););if(d.p.compareTo(d.q)<=0){var i=d.p;d.p=d.q,d.q=i}var j=d.p.subtract(e.ONE),k=d.q.subtract(e.ONE),l=j.multiply(k);if(0==l.gcd(d.ee).compareTo(e.ONE)){d.n=d.p.multiply(d.q),d.d=d.ee.modInverse(l),d.dmp1=d.d.mod(j),d.dmq1=d.d.mod(k),d.u=d.p.modInverse(d.q);break}}return d}this.encrypt=b,this.decrypt=a,this.verify=g,this.sign=d,this.generate=i,this.keyObject=h}var e=a("./jsbn.js"),f=a("../../util"),g=a("../random.js");b.exports=d},{"../../util":56,"../random.js":23,"./jsbn.js":21}],23:[function(a,b){var c=a("../type/mpi.js");b.exports={getRandomBytes:function(a){for(var b="",c=0;a>c;c++)b+=String.fromCharCode(this.getSecureRandomOctet());return b},getPseudoRandom:function(a,b){return Math.round(Math.random()*(b-a))+a},getSecureRandom:function(a,b){var c=new Uint32Array(1);window.crypto.getRandomValues(c);for(var d=(b-a).toString(2).length;(c[0]&Math.pow(2,d)-1)>b-a;)window.crypto.getRandomValues(c);return a+Math.abs(c[0]&Math.pow(2,d)-1)},getSecureRandomOctet:function(){var a=new Uint32Array(1);return window.crypto.getRandomValues(a),255&a[0]},getRandomBigInteger:function(a){if(0>a)return null;var b=Math.floor((a+7)/8),d=this.getRandomBytes(b);a%8>0&&(d=String.fromCharCode(Math.pow(2,a%8)-1&d.charCodeAt(0))+d.substring(1));var e=new c;return e.fromBytes(d),e.toBigInteger()},getRandomBigIntegerInRange:function(a,b){if(!(b.compareTo(a)<=0)){for(var c=b.subtract(a),d=this.getRandomBigInteger(c.bitLength());d>c;)d=this.getRandomBigInteger(c.bitLength());return a.add(d)}}}},{"../type/mpi.js":54}],24:[function(a,b){var c=a("./public_key"),d=a("./pkcs1.js"),e=a("./hash");b.exports={verify:function(a,b,f,g,h){var i=e.digest(b,h);switch(a){case 1:case 2:case 3:var j=new c.rsa,k=g[0].toBigInteger(),l=g[1].toBigInteger(),m=f[0].toBigInteger(),n=j.verify(m,l,k),o=d.emsa.decode(b,n.toMPI().substring(2));if(-1==o)throw new Error("PKCS1 padding in message or key incorrect. Aborting...");return o==i;case 16:throw new Error("signing with Elgamal is not defined in the OpenPGP standard.");case 17:var p=new c.dsa,q=f[0].toBigInteger(),r=f[1].toBigInteger(),s=g[0].toBigInteger(),t=g[1].toBigInteger(),u=g[2].toBigInteger(),v=g[3].toBigInteger(),w=h,n=p.verify(b,q,r,w,s,t,u,v);return 0==n.compareTo(q);default:throw new Error("Invalid signature algorithm.")}},sign:function(a,b,e,f){switch(b){case 1:case 2:case 3:var g=new c.rsa,h=e[2].toBigInteger(),i=e[0].toBigInteger(),j=d.emsa.encode(a,f,e[0].byteLength());return g.sign(j,h,i).toMPI();case 17:var k=new c.dsa,l=e[0].toBigInteger(),m=e[1].toBigInteger(),n=e[2].toBigInteger(),o=(e[3].toBigInteger(),e[4].toBigInteger()),j=f,p=k.sign(a,j,n,l,m,o);return p[0].toString()+p[1].toString();case 16:throw new Error("Signing with Elgamal is not defined in the OpenPGP standard.");default:throw new Error("Invalid signature algorithm.")}}}},{"./hash":12,"./pkcs1.js":17,"./public_key":20}],25:[function(a,b){function c(a){var b=/^-----([^-]+)-----$\n/m,c=a.match(b);return c[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)?m.armor.multipart_section:c[1].match(/BEGIN PGP MESSAGE, PART \d+/)?m.armor.multipart_last:c[1].match(/BEGIN PGP SIGNED MESSAGE/)?m.armor.signed:c[1].match(/BEGIN PGP MESSAGE/)?m.armor.message:c[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)?m.armor.public_key:c[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)?m.armor.private_key:void 0}function d(){var a="";return n.show_version&&(a+="Version: "+n.versionstring+"\r\n"),n.show_comment&&(a+="Comment: "+n.commentstring+"\r\n"),a+="\r\n"}function e(a){var b=g(a),c=""+String.fromCharCode(b>>16)+String.fromCharCode(b>>8&255)+String.fromCharCode(255&b);return l.encode(c)}function f(a,b){var c=e(a),d=b;return c[0]==d[0]&&c[1]==d[1]&&c[2]==d[2]}function g(a){for(var b=11994318,c=0;a.length-c>16;)b=b<<8^o[255&(b>>16^a.charCodeAt(c))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+1))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+2))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+3))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+4))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+5))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+6))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+7))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+8))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+9))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+10))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+11))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+12))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+13))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+14))],b=b<<8^o[255&(b>>16^a.charCodeAt(c+15))],c+=16;for(var d=c;d>16^a.charCodeAt(c++))];return 16777215&b}function h(a){var b=/^[\t ]*\n/m,c="",d=a,e=b.exec(a);return null!=e&&(c=a.slice(0,e.index),d=a.slice(e.index+e[0].length)),{headers:c,body:d}}function i(a){var b=/^=/m,c=a,d="",e=b.exec(a);return null!=e&&(c=a.slice(0,e.index),d=a.slice(e.index+1)),{body:c,checksum:d}}function j(a){var b=/^-----[^-]+-----$\n/m;a=a.replace(/\r/g,"");var d=c(a);if(!d)throw new Error("Unknow ASCII armor type");var g,j,k=a.split(b),m=1;if(a.search(b)!=k[0].length&&(m=0),2!=d){var n=h(k[m]),o=i(n.body);g={data:l.decode(o.body),type:d},j=o.checksum}else{var n=h(k[m].replace(/^- /gm,"").replace(/[\t ]+\n/g,"\n")),p=h(k[m+1].replace(/^- /gm,"")),q=i(p.body);g={text:n.body.replace(/\n$/,"").replace(/\n/g,"\r\n"),data:l.decode(q.body),type:d},j=q.checksum}if(f(g.data,j))return g;throw new Error("Ascii armor integrity check on message failed: '"+j+"' should be '"+e(g)+"'")}function k(a,b,c,f){var g="";switch(a){case m.armor.multipart_section:g+="-----BEGIN PGP MESSAGE, PART "+c+"/"+f+"-----\r\n",g+=d(),g+=l.encode(b),g+="\r\n="+e(b)+"\r\n",g+="-----END PGP MESSAGE, PART "+c+"/"+f+"-----\r\n";break;case m.armor.mutlipart_last:g+="-----BEGIN PGP MESSAGE, PART "+c+"-----\r\n",g+=d(),g+=l.encode(b),g+="\r\n="+e(b)+"\r\n",g+="-----END PGP MESSAGE, PART "+c+"-----\r\n";break;case m.armor.signed:g+="\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\n",g+="Hash: "+b.hash+"\r\n\r\n",g+=b.text.replace(/\n-/g,"\n- -"),g+="\r\n-----BEGIN PGP SIGNATURE-----\r\n",g+=d(),g+=l.encode(b.data),g+="\r\n="+e(b.data)+"\r\n",g+="-----END PGP SIGNATURE-----\r\n";break;case m.armor.message:g+="-----BEGIN PGP MESSAGE-----\r\n",g+=d(),g+=l.encode(b),g+="\r\n="+e(b)+"\r\n",g+="-----END PGP MESSAGE-----\r\n";break;case m.armor.public_key:g+="-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n",g+=d(),g+=l.encode(b),g+="\r\n="+e(b)+"\r\n",g+="-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n";break;case m.armor.private_key:g+="-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n",g+=d(),g+=l.encode(b),g+="\r\n="+e(b)+"\r\n",g+="-----END PGP PRIVATE KEY BLOCK-----\r\n"}return g}var l=a("./base64.js"),m=a("../enums.js"),n=a("../config"),o=[0,8801531,25875725,17603062,60024545,51751450,35206124,44007191,128024889,120049090,103502900,112007375,70412248,78916387,95990485,88014382,264588937,256049778,240098180,248108927,207005800,215016595,232553829,224014750,140824496,149062475,166599357,157832774,200747345,191980970,176028764,184266919,520933865,529177874,512099556,503334943,480196360,471432179,487973381,496217854,414011600,405478443,422020573,430033190,457094705,465107658,448029500,439496647,281648992,273666971,289622637,298124950,324696449,333198714,315665548,307683447,392699481,401494690,383961940,375687087,352057528,343782467,359738805,368533838,1041867730,1050668841,1066628831,1058355748,1032471859,1024199112,1006669886,1015471301,968368875,960392720,942864358,951368477,975946762,984451313,1000411399,992435708,836562267,828023200,810956886,818967725,844041146,852051777,868605623,860066380,914189410,922427545,938981743,930215316,904825475,896059e3,878993294,887231349,555053627,563297984,547333942,538569677,579245274,570480673,588005847,596249900,649392898,640860153,658384399,666397428,623318499,631331096,615366894,606833685,785398962,777416777,794487231,802989380,759421523,767923880,751374174,743392165,695319947,704115056,687564934,679289981,719477610,711202705,728272487,737067676,2083735460,2092239711,2109313705,2101337682,2141233477,2133257662,2116711496,2125215923,2073216669,2064943718,2048398224,2057199467,2013339772,2022141063,2039215473,2030942602,1945504045,1936737750,1920785440,1929023707,1885728716,1893966647,1911503553,1902736954,1951893524,1959904495,1977441561,1968902626,2009362165,2000822798,1984871416,1992881923,1665111629,1673124534,1656046400,1647513531,1621913772,1613380695,1629922721,1637935450,1688082292,1679317903,1695859321,1704103554,1728967061,1737211246,1720132760,1711368291,1828378820,1820103743,1836060105,1844855090,1869168165,1877963486,1860430632,1852155859,1801148925,1809650950,1792118e3,1784135691,1757986588,1750004711,1765960209,1774462698,1110107254,1118611597,1134571899,1126595968,1102643863,1094667884,1077139354,1085643617,1166763343,1158490548,1140961346,1149762745,1176011694,1184812885,1200772771,1192499800,1307552511,1298785796,1281720306,1289958153,1316768798,1325007077,1341561107,1332794856,1246636998,1254647613,1271201483,1262662192,1239272743,1230733788,1213667370,1221678289,1562785183,1570797924,1554833554,1546300521,1588974462,1580441477,1597965939,1605978760,1518843046,1510078557,1527603627,1535847760,1494504007,1502748348,1486784330,1478020017,1390639894,1382365165,1399434779,1408230112,1366334967,1375129868,1358579962,1350304769,1430452783,1438955220,1422405410,1414423513,1456544974,1448562741,1465633219,1474135352]; -b.exports={encode:k,decode:j}},{"../config":3,"../enums.js":27,"./base64.js":26}],26:[function(a,b){function c(a){var b,c,d,f="",g=0,h=0,i=a.length;for(d=0;i>d;d++)c=a.charCodeAt(d),0==h?(f+=e.charAt(c>>2&63),b=(3&c)<<4):1==h?(f+=e.charAt(b|c>>4&15),b=(15&c)<<2):2==h&&(f+=e.charAt(b|c>>6&3),g+=1,g%60==0&&(f+="\n"),f+=e.charAt(63&c)),g+=1,g%60==0&&(f+="\n"),h+=1,3==h&&(h=0);return h>0&&(f+=e.charAt(b),g+=1,g%60==0&&(f+="\n"),f+="=",g+=1),1==h&&(g%60==0&&(f+="\n"),f+="="),f}function d(a){var b,c,d="",f=0,g=0,h=a.length;for(c=0;h>c;c++)b=e.indexOf(a.charAt(c)),b>=0&&(f&&(d+=String.fromCharCode(g|b>>6-f&255)),f=f+2&7,g=b<this.primaryKey.created.getTime()+24*this.primaryKey.expirationTimeV3*3600*1e3)return m.keyStatus.expired;for(var a=!1,b=0;bc.selfCertificate.created.getTime()+1e3*c.selfCertificate.keyExpirationTime?m.keyStatus.expired:m.keyStatus.valid:m.keyStatus.invalid},d.prototype.getPrimaryUser=function(){for(var a,b=null,c=0;cb?-1:b>a?1:0}),b[0]},h.prototype.verify=function(a){if(!this.selfCertifications)return m.keyStatus.no_self_cert;for(var b,c=0;cthis.subKey.created.getTime()+24*this.subKey.expirationTimeV3*3600*1e3?m.keyStatus.expired:this.bindingSignature?this.bindingSignature.isExpired()?m.keyStatus.expired:this.bindingSignature.verified||this.bindingSignature.verify(a,{key:a,bind:this.subKey})?4==this.subKey.version&&this.bindingSignature.keyNeverExpires===!1&&Date.now()>this.subKey.created.getTime()+1e3*this.bindingSignature.keyExpirationTime?m.keyStatus.expired:m.keyStatus.valid:m.keyStatus.invalid:m.keyStatus.invalid},c.Key=d,c.readArmored=j,c.generate=k},{"./config":3,"./encoding/armor.js":25,"./enums.js":27,"./packet":35}],31:[function(a,b,c){function d(a){return this instanceof d?(this.packets=a||new h.list,void 0):new d(a)}function e(a){var b=j.decode(a).data,c=new h.list;c.read(b);var e=new d(c);return e}function f(a){var b=new h.literal;b.setText(a);var c=new h.list;c.push(b);var e=new d(c);return e}function g(a){var b=new h.literal;b.setBytes(a,i.read(i.literal,i.literal.binary));var c=new h.list;c.push(b);var e=new d(c);return e}{var h=a("./packet"),i=a("./enums.js"),j=a("./encoding/armor.js"),k=a("./config"),l=a("./crypto");a("./util")}d.prototype.getEncryptionKeyIds=function(){var a=[],b=this.packets.filterByTag(i.packet.public_key_encrypted_session_key);return b.forEach(function(b){a.push(b.publicKeyId)}),a},d.prototype.getSigningKeyIds=function(){var a=[],b=this.unwrapCompressed(),c=b.packets.filterByTag(i.packet.one_pass_signature);if(c.forEach(function(b){a.push(b.signingKeyId)}),!a.length){var d=b.packets.filterByTag(i.packet.signature);d.forEach(function(b){a.push(b.issuerKeyId)})}return a},d.prototype.decrypt=function(a){var b=this.getEncryptionKeyIds();if(!b.length)return this;var c=a.getPrivateKeyPacket(b);if(!c.isDecrypted)throw new Error("Private key is not decrypted.");for(var e,f=this.packets.filterByTag(i.packet.public_key_encrypted_session_key),g=0;g=0;g--){var m=new h.signature;if(m.signatureType=f,m.hashAlgorithm=k.prefer_hash_algorithm,m.publicKeyAlgorithm=l.algorithm,!l.isDecrypted)throw new Error("Private key is not decrypted.");m.sign(l,c),b.push(m)}return new d(b)},d.prototype.verify=function(a){var b=[],c=this.unwrapCompressed(),d=c.packets.filterByTag(i.packet.literal);if(1!==d.length)throw new Error("Can only verify message with one literal data packet.");var e=c.packets.filterByTag(i.packet.signature);return a.forEach(function(a){for(var c=0;ce?(d=a.charCodeAt(0),b=1):255>e?(d=(a.charCodeAt(0)-192<<8)+a.charCodeAt(1)+192,b=2):255==e&&(d=c.readNumber(a.substr(1,4)),b=5),{len:d,offset:b}},writeSimpleLength:function(a){var b="";return 192>a?b+=String.fromCharCode(a):a>191&&8384>a?(b+=String.fromCharCode((a-192>>8)+192),b+=String.fromCharCode(a-192&255)):(b+=String.fromCharCode(255),b+=c.writeNumber(a,4)),b},writeHeader:function(a,b){var c="";return c+=String.fromCharCode(192|a),c+=this.writeSimpleLength(b)},writeOldHeader:function(a,b){var d="";return 256>b?(d+=String.fromCharCode(128|a<<2),d+=String.fromCharCode(b)):65536>b?(d+=String.fromCharCode(128|a<<2|1),d+=c.writeNumber(b,2)):(d+=String.fromCharCode(128|a<<2|2),d+=c.writeNumber(b,4)),d},read:function(a,b,d){if(null==a||a.length<=b||a.substring(b).length<2||0==(128&a.charCodeAt(b)))throw new Error("Error during parsing. This message / key is probably not containing a valid OpenPGP format.");var e,f=b,g=-1,h=-1;h=0,0!=(64&a.charCodeAt(f))&&(h=1);var i;h?g=63&a.charCodeAt(f):(g=(63&a.charCodeAt(f))>>2,i=3&a.charCodeAt(f)),f++;var j=null,k=-1;if(h)if(a.charCodeAt(f)<192)e=a.charCodeAt(f++),c.print_debug("1 byte length:"+e);else if(a.charCodeAt(f)>=192&&a.charCodeAt(f)<224)e=(a.charCodeAt(f++)-192<<8)+a.charCodeAt(f++)+192,c.print_debug("2 byte length:"+e);else if(a.charCodeAt(f)>223&&a.charCodeAt(f)<255){e=1<<(31&a.charCodeAt(f++)),c.print_debug("4 byte length:"+e);var l=f+e;for(j=a.substring(f,f+e);;){if(a.charCodeAt(l)<192){var m=a.charCodeAt(l++);e+=m,j+=a.substring(l,l+m),l+=m;break}if(a.charCodeAt(l)>=192&&a.charCodeAt(l)<224){var m=(a.charCodeAt(l++)-192<<8)+a.charCodeAt(l++)+192;e+=m,j+=a.substring(l,l+m),l+=m;break}if(!(a.charCodeAt(l)>223&&a.charCodeAt(l)<255)){l++;var m=a.charCodeAt(l++)<<24|a.charCodeAt(l++)<<16|a[l++].charCodeAt()<<8|a.charCodeAt(l++);j+=a.substring(l,l+m),e+=m,l+=m;break}var m=1<<(31&a.charCodeAt(l++));e+=m,j+=a.substring(l,l+m),l+=m}k=l}else f++,e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);else switch(i){case 0:e=a.charCodeAt(f++);break;case 1:e=a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;case 2:e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;default:e=d}return-1==k&&(k=e),null==j&&(j=a.substring(f,f+k)),{tag:g,packet:j,offset:f+k}}}},{"../enums.js":27,"../util":56}],40:[function(a,b){var c=a("./packet.js"),d=a("./all_packets.js"),e=a("../enums.js");b.exports=function f(){this.length=0,this.read=function(a){for(var b=0;bd;d++)c.push(this[d]);return c},this.concat=function(a){if(a)for(var b=0;bj&&ih.length)throw new Error("Error reading MPI @:"+i);return i+6}throw new Error("Version "+version+" of the key packet is unsupported.")},this.writePublicKey=this.write=function(){var a=String.fromCharCode(this.version);a+=c.writeDate(this.created),3==this.version&&(a+=c.writeNumber(this.expirationTimeV3,2)),a+=String.fromCharCode(f.write(f.publicKey,this.algorithm));for(var b=g.getPublicMpiCount(this.algorithm),d=0;b>d;d++)a+=this.mpi[d].write();return a},this.writeOld=function(){var a=this.writePublicKey();return String.fromCharCode(153)+c.writeNumber(a.length,2)+a},this.getKeyId=function(){var a=new e;return 4==this.version?a.read(this.getFingerprint().substr(12,8)):3==this.version&&a.read(this.mpi[0].write().substr(-8)),a},this.getFingerprint=function(){var a="";if(4==this.version)return a=this.writeOld(),g.hash.sha1(a);if(3==this.version){for(var b=g.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].toBytes();return g.hash.md5(a)}}}},{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56}],42:[function(a,b){var c=a("../type/keyid.js"),d=a("../util"),e=a("../type/mpi.js"),f=a("../enums.js"),g=a("../crypto");b.exports=function(){this.version=3,this.publicKeyId=new c,this.publicKeyAlgorithm="rsa_encrypt",this.sessionKey=null,this.sessionKeyAlgorithm="aes256",this.encrypted=[],this.read=function(a){this.version=a.charCodeAt(0),this.publicKeyId.read(a.substr(1)),this.publicKeyAlgorithm=f.read(f.publicKey,a.charCodeAt(9));var b=10,c=function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":return 1;case"elgamal":return 2;default:throw new Error("Invalid algorithm.")}}(this.publicKeyAlgorithm);this.encrypted=[];for(var d=0;c>d;d++){var g=new e;b+=g.read(a.substr(b)),this.encrypted.push(g)}},this.write=function(){var a=String.fromCharCode(this.version);a+=this.publicKeyId.write(),a+=String.fromCharCode(f.write(f.publicKey,this.publicKeyAlgorithm));for(var b=0;bo&&me;){var f=d.readSimpleLength(a.substr(e));e+=f.offset,this.read_sub_packet(a.substr(e,f.len)),e+=f.len}return e}var e=0;switch(this.version=a.charCodeAt(e++),this.version){case 3:5!=a.charCodeAt(e++)&&c.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(e-1));var f=e;this.signatureType=a.charCodeAt(e++),this.created=c.readDate(a.substr(e,4)),e+=4,this.signatureData=a.substring(f,e),this.issuerKeyId.read(a.substring(e,e+8)),e+=8,this.publicKeyAlgorithm=a.charCodeAt(e++),this.hashAlgorithm=a.charCodeAt(e++);break;case 4:this.signatureType=a.charCodeAt(e++),this.publicKeyAlgorithm=a.charCodeAt(e++),this.hashAlgorithm=a.charCodeAt(e++),e+=b.call(this,a.substr(e),!0),this.signatureData=a.substr(0,e),e+=b.call(this,a.substr(e),!1);break;default:throw new Error("Version "+version+" of the signature is unsupported.")}this.signedHashValue=a.substr(e,2),e+=2,this.signature=a.substr(e)},this.write=function(){return this.signatureData+c.writeNumber(0,2)+this.signedHashValue+this.signature},this.sign=function(a,b){var c=e.write(e.signature,this.signatureType),d=e.write(e.publicKey,this.publicKeyAlgorithm),g=e.write(e.hash,this.hashAlgorithm),h=String.fromCharCode(4);h+=String.fromCharCode(c),h+=String.fromCharCode(d),h+=String.fromCharCode(g),this.issuerKeyId=a.getKeyId(),h+=this.write_all_sub_packets(),this.signatureData=h;var i=this.calculateTrailer(),j=this.toSign(c,b)+this.signatureData+i,k=f.hash.digest(g,j);this.signedHashValue=k.substr(0,2),this.signature=f.signature.sign(g,d,a.mpi,j)},this.write_all_sub_packets=function(){var b=e.signatureSubpacket,d="",f="";if(null!==this.created&&(d+=a(b.signature_creation_time,c.writeDate(this.created))),null!==this.signatureExpirationTime&&(d+=a(b.signature_expiration_time,c.writeNumber(this.signatureExpirationTime,4))),null!==this.exportable&&(d+=a(b.exportable_certification,String.fromCharCode(this.exportable?1:0))),null!==this.trustLevel&&(f=String.fromCharCode(this.trustLevel)+String.fromCharCode(this.trustAmount),d+=a(b.trust_signature,f)),null!==this.regularExpression&&(d+=a(b.regular_expression,this.regularExpression)),null!==this.revocable&&(d+=a(b.revocable,String.fromCharCode(this.revocable?1:0))),null!==this.keyExpirationTime&&(d+=a(b.key_expiration_time,c.writeNumber(this.keyExpirationTime,4))),null!==this.preferredSymmetricAlgorithms&&(f=c.bin2str(this.preferredSymmetricAlgorithms),d+=a(b.preferred_symmetric_algorithms,f)),null!==this.revocationKeyClass&&(f=String.fromCharCode(this.revocationKeyClass),f+=String.fromCharCode(this.revocationKeyAlgorithm),f+=this.revocationKeyFingerprint,d+=a(b.revocation_key,f)),this.issuerKeyId.isNull()||(d+=a(b.issuer,this.issuerKeyId.write())),null!==this.notation)for(var g in this.notation)if(this.notation.hasOwnProperty(g)){var h=this.notation[g];f=String.fromCharCode(128),f+=String.fromCharCode(0),f+=String.fromCharCode(0),f+=String.fromCharCode(0),f+=c.writeNumber(g.length,2),f+=c.writeNumber(h.length,2),f+=g+h,d+=a(b.notation_data,f)}return null!==this.preferredHashAlgorithms&&(f=c.bin2str(this.preferredHashAlgorithms),d+=a(b.preferred_hash_algorithms,f)),null!==this.preferredCompressionAlgorithms&&(f=c.bin2str(this.preferredCompressionAlgorithms),d+=a(b.preferred_hash_algorithms,f)),null!==this.keyServerPreferences&&(f=c.bin2str(this.keyServerPreferences),d+=a(b.key_server_preferences,f)),null!==this.preferredKeyServer&&(d+=a(b.preferred_key_server,this.preferredKeyServer)),null!==this.isPrimaryUserID&&(d+=a(b.primary_user_id,String.fromCharCode(this.isPrimaryUserID?1:0))),null!==this.policyURI&&(d+=a(b.policy_uri,this.policyURI)),null!==this.keyFlags&&(f=c.bin2str(this.keyFlags),d+=a(b.key_flags,f)),null!==this.signersUserId&&(d+=a(b.signers_user_id,this.signersUserId)),null!==this.reasonForRevocationFlag&&(f=String.fromCharCode(this.reasonForRevocationFlag),f+=this.reasonForRevocationString,d+=a(b.reason_for_revocation,f)),null!==this.features&&(f=c.bin2str(this.features),d+=a(b.features,f)),null!==this.signatureTargetPublicKeyAlgorithm&&(f=String.fromCharCode(this.signatureTargetPublicKeyAlgorithm),f+=String.fromCharCode(this.signatureTargetHashAlgorithm),f+=this.signatureTargetHash,d+=a(b.signature_target,f)),null!==this.embeddedSignature&&(d+=a(b.embedded_signature,this.embeddedSignature.write())),d=c.writeNumber(d.length,2)+d},this.read_sub_packet=function(a){function b(a,b){this[a]=[];for(var c=0;c0&&4>d?k=1:17==d&&(k=2);for(var l=[],m=0,n=0;k>n;n++)l[n]=new g,m+=l[n].read(this.signature.substr(m));return this.verified=f.signature.verify(d,h,l,a.mpi,i+this.signatureData+j),this.verified},this.isExpired=function(){return this.signatureNeverExpires?!1:Date.now()>this.created.getTime()+1e3*this.signatureExpirationTime}}},{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56,"./packet.js":39}],47:[function(a,b){var c=(a("../util"),a("../crypto"));b.exports=function(){this.encrypted=null,this.modification=!1,this.packets,this.read=function(a){var b=a.charCodeAt(0);if(1!=b)throw new Error("Invalid packet version.");this.encrypted=a.substr(1)},this.write=function(){return String.fromCharCode(1)+this.encrypted},this.encrypt=function(a,b){var d=this.packets.write(),e=c.getPrefixRandom(a),f=e+e.charAt(e.length-2)+e.charAt(e.length-1),g=d;g+=String.fromCharCode(211),g+=String.fromCharCode(20),g+=c.hash.sha1(f+g),this.encrypted=c.cfb.encrypt(e,a,g,b,!1).substring(0,f.length+g.length)},this.decrypt=function(a,b){var d=c.cfb.decrypt(a,b,this.encrypted,!1);this.hash=c.hash.sha1(c.cfb.mdc(a,b,this.encrypted)+d.substring(0,d.length-20));var e=d.substr(d.length-20,20);if(this.hash!=e)throw new Error("Modification detected.");this.packets.read(d.substr(0,d.length-22))}}},{"../crypto":16,"../util":56}],48:[function(a,b){var c=a("../type/s2k.js"),d=a("../enums.js"),e=a("../crypto");b.exports=function(){this.tag=3,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new c,this.read=function(a){this.version=a.charCodeAt(0);var b=d.read(d.symmetric,a.charCodeAt(1)),c=this.s2k.read(a.substr(2)),e=c+2;e>4)+a},this.read=function(a){var b=0;switch(this.type=c.read(c.s2k,a.charCodeAt(b++)),this.algorithm=c.read(c.hash,a.charCodeAt(b++)),this.type){case"simple":break;case"salted":this.salt=a.substr(b,8),b+=8;break;case"iterated":this.salt=a.substr(b,8),b+=8,this.c=a.charCodeAt(b++);break;case"gnu":if("GNU"!=a.substr(b,3))throw new Error("Unknown s2k type.");b+=3;var d=1e3+a.charCodeAt(b++);if(1001!=d)throw new Error("Unknown s2k gnu protection mode.");this.type=d;break;default:throw new Error("Unknown s2k type.")}return b},this.write=function(){var a=String.fromCharCode(c.write(c.s2k,this.type));switch(a+=String.fromCharCode(c.write(c.hash,this.algorithm)),this.type){case"simple":break;case"salted":a+=this.salt;break;case"iterated":a+=this.salt,a+=String.fromCharCode(this.c)}return a},this.produce_key=function(a,b){function f(b,d){var f=c.write(c.hash,d.algorithm);switch(d.type){case"simple":return e.hash.digest(f,b+a);case"salted":return e.hash.digest(f,b+d.salt+a);case"iterated":var g=[],h=d.get_count();for(data=d.salt+a;g.length*data.lengthh&&(g=g.substr(0,h)),e.hash.digest(f,b+g)}}a=d.encode_utf8(a);for(var g="",h="";g.length<=b;)g+=f(h,this),h+=String.fromCharCode(0);return g.substr(0,b)}}},{"../crypto":16,"../enums.js":27,"../util":56}],56:[function(a,b){var c=a("../config"),d=function(){this.readNumber=function(a){for(var b=0,c=0;cd;d++)c+=String.fromCharCode(a>>8*(b-d-1)&255);return c},this.readDate=function(a){var b=this.readNumber(a),c=new Date;return c.setTime(1e3*b),c},this.writeDate=function(a){var b=Math.round(a.getTime()/1e3);return this.writeNumber(b,4)},this.emailRegEx=/^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/,this.debug=!1,this.hexdump=function(a){for(var b,c=[],d=a.length,e=0,f=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(" "+b),f++,f%32==0&&c.push("\n ")}return c.join("")},this.hexstrdump=function(a){if(null==a)return"";for(var b,c=[],d=a.length,e=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},this.hex2bin=function(a){for(var b="",c=0;ce;){for(b=a[e++].toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},this.encode_utf8=function(a){return unescape(encodeURIComponent(a))},this.decode_utf8=function(a){try{return decodeURIComponent(escape(a))}catch(b){return a}};var a=function(a,b){for(var c=0;c=0;d--)c[d]>>=b%8,d>0&&(c[d]|=c[d-1]<<8-b%8&255);return util.bin2str(c)},this.get_hashAlgorithmString=function(a){switch(a){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}};b.exports=new d},{"../config":3}]},{},[]); \ No newline at end of file +b.exports={encode:k,decode:j}},{"../config":3,"../enums.js":27,"./base64.js":26}],26:[function(a,b){function c(a){var b,c,d,f="",g=0,h=0,i=a.length;for(d=0;i>d;d++)c=a.charCodeAt(d),0==h?(f+=e.charAt(c>>2&63),b=(3&c)<<4):1==h?(f+=e.charAt(b|c>>4&15),b=(15&c)<<2):2==h&&(f+=e.charAt(b|c>>6&3),g+=1,g%60==0&&(f+="\n"),f+=e.charAt(63&c)),g+=1,g%60==0&&(f+="\n"),h+=1,3==h&&(h=0);return h>0&&(f+=e.charAt(b),g+=1,g%60==0&&(f+="\n"),f+="=",g+=1),1==h&&(g%60==0&&(f+="\n"),f+="="),f}function d(a){var b,c,d="",f=0,g=0,h=a.length;for(c=0;h>c;c++)b=e.indexOf(a.charAt(c)),b>=0&&(f&&(d+=String.fromCharCode(g|b>>6-f&255)),f=f+2&7,g=b<this.primaryKey.created.getTime()+24*this.primaryKey.expirationTimeV3*3600*1e3)return m.keyStatus.expired;for(var a=!1,b=0;bc.selfCertificate.created.getTime()+1e3*c.selfCertificate.keyExpirationTime?m.keyStatus.expired:m.keyStatus.valid:m.keyStatus.invalid},d.prototype.getPrimaryUser=function(){for(var a,b=null,c=0;cb?-1:b>a?1:0}),b[0]},h.prototype.verify=function(a){if(!this.selfCertifications)return m.keyStatus.no_self_cert;for(var b,c=0;cthis.subKey.created.getTime()+24*this.subKey.expirationTimeV3*3600*1e3?m.keyStatus.expired:this.bindingSignature?this.bindingSignature.isExpired()?m.keyStatus.expired:this.bindingSignature.verified||this.bindingSignature.verify(a,{key:a,bind:this.subKey})?4==this.subKey.version&&this.bindingSignature.keyNeverExpires===!1&&Date.now()>this.subKey.created.getTime()+1e3*this.bindingSignature.keyExpirationTime?m.keyStatus.expired:m.keyStatus.valid:m.keyStatus.invalid:m.keyStatus.invalid},c.Key=d,c.readArmored=j,c.generate=k},{"./config":3,"./encoding/armor.js":25,"./enums.js":27,"./packet":35}],31:[function(a,b,c){function d(a){return this instanceof d?(this.packets=a||new h.list,void 0):new d(a)}function e(a){var b=j.decode(a).data,c=new h.list;c.read(b);var e=new d(c);return e}function f(a){var b=new h.literal;b.setText(a);var c=new h.list;c.push(b);var e=new d(c);return e}function g(a){var b=new h.literal;b.setBytes(a,i.read(i.literal,i.literal.binary));var c=new h.list;c.push(b);var e=new d(c);return e}var h=a("./packet"),i=a("./enums.js"),j=a("./encoding/armor.js"),k=a("./config"),l=a("./crypto");d.prototype.getEncryptionKeyIds=function(){var a=[],b=this.packets.filterByTag(i.packet.public_key_encrypted_session_key);return b.forEach(function(b){a.push(b.publicKeyId)}),a},d.prototype.getSigningKeyIds=function(){var a=[],b=this.unwrapCompressed(),c=b.packets.filterByTag(i.packet.one_pass_signature);if(c.forEach(function(b){a.push(b.signingKeyId)}),!a.length){var d=b.packets.filterByTag(i.packet.signature);d.forEach(function(b){a.push(b.issuerKeyId)})}return a},d.prototype.decrypt=function(a){var b=this.getEncryptionKeyIds();if(!b.length)return this;var c=a.getPrivateKeyPacket(b);if(!c.isDecrypted)throw new Error("Private key is not decrypted.");for(var e,f=this.packets.filterByTag(i.packet.public_key_encrypted_session_key),g=0;g=0;g--){var m=new h.signature;if(m.signatureType=f,m.hashAlgorithm=k.prefer_hash_algorithm,m.publicKeyAlgorithm=l.algorithm,!l.isDecrypted)throw new Error("Private key is not decrypted.");m.sign(l,c),b.push(m)}return new d(b)},d.prototype.verify=function(a){var b=[],c=this.unwrapCompressed(),d=c.packets.filterByTag(i.packet.literal);if(1!==d.length)throw new Error("Can only verify message with one literal data packet.");var e=c.packets.filterByTag(i.packet.signature);return a.forEach(function(a){for(var c=0;ce?(d=a.charCodeAt(0),b=1):255>e?(d=(a.charCodeAt(0)-192<<8)+a.charCodeAt(1)+192,b=2):255==e&&(d=c.readNumber(a.substr(1,4)),b=5),{len:d,offset:b}},writeSimpleLength:function(a){var b="";return 192>a?b+=String.fromCharCode(a):a>191&&8384>a?(b+=String.fromCharCode((a-192>>8)+192),b+=String.fromCharCode(a-192&255)):(b+=String.fromCharCode(255),b+=c.writeNumber(a,4)),b},writeHeader:function(a,b){var c="";return c+=String.fromCharCode(192|a),c+=this.writeSimpleLength(b)},writeOldHeader:function(a,b){var d="";return 256>b?(d+=String.fromCharCode(128|a<<2),d+=String.fromCharCode(b)):65536>b?(d+=String.fromCharCode(128|a<<2|1),d+=c.writeNumber(b,2)):(d+=String.fromCharCode(128|a<<2|2),d+=c.writeNumber(b,4)),d},read:function(a,b,d){if(null==a||a.length<=b||a.substring(b).length<2||0==(128&a.charCodeAt(b)))throw new Error("Error during parsing. This message / key is probably not containing a valid OpenPGP format.");var e,f=b,g=-1,h=-1;h=0,0!=(64&a.charCodeAt(f))&&(h=1);var i;h?g=63&a.charCodeAt(f):(g=(63&a.charCodeAt(f))>>2,i=3&a.charCodeAt(f)),f++;var j=null,k=-1;if(h)if(a.charCodeAt(f)<192)e=a.charCodeAt(f++),c.print_debug("1 byte length:"+e);else if(a.charCodeAt(f)>=192&&a.charCodeAt(f)<224)e=(a.charCodeAt(f++)-192<<8)+a.charCodeAt(f++)+192,c.print_debug("2 byte length:"+e);else if(a.charCodeAt(f)>223&&a.charCodeAt(f)<255){e=1<<(31&a.charCodeAt(f++)),c.print_debug("4 byte length:"+e);var l=f+e;for(j=a.substring(f,f+e);;){if(a.charCodeAt(l)<192){var m=a.charCodeAt(l++);e+=m,j+=a.substring(l,l+m),l+=m;break}if(a.charCodeAt(l)>=192&&a.charCodeAt(l)<224){var m=(a.charCodeAt(l++)-192<<8)+a.charCodeAt(l++)+192;e+=m,j+=a.substring(l,l+m),l+=m;break}if(!(a.charCodeAt(l)>223&&a.charCodeAt(l)<255)){l++;var m=a.charCodeAt(l++)<<24|a.charCodeAt(l++)<<16|a[l++].charCodeAt()<<8|a.charCodeAt(l++);j+=a.substring(l,l+m),e+=m,l+=m;break}var m=1<<(31&a.charCodeAt(l++));e+=m,j+=a.substring(l,l+m),l+=m}k=l}else f++,e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);else switch(i){case 0:e=a.charCodeAt(f++);break;case 1:e=a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;case 2:e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;default:e=d}return-1==k&&(k=e),null==j&&(j=a.substring(f,f+k)),{tag:g,packet:j,offset:f+k}}}},{"../enums.js":27,"../util":56}],40:[function(a,b){var c=a("./packet.js"),d=a("./all_packets.js"),e=a("../enums.js");b.exports=packetlist=function(){this.length=0,this.read=function(a){for(var b=0;bd;d++)c.push(this[d]);return c},this.concat=function(a){if(a)for(var b=0;bj&&ih.length)throw new Error("Error reading MPI @:"+i);return i+6}throw new Error("Version "+version+" of the key packet is unsupported.")},this.readPublicKey=this.read,this.write=function(){var a=String.fromCharCode(this.version);a+=c.writeDate(this.created),3==this.version&&(a+=c.writeNumber(this.expirationTimeV3,2)),a+=String.fromCharCode(f.write(f.publicKey,this.algorithm));for(var b=g.getPublicMpiCount(this.algorithm),d=0;b>d;d++)a+=this.mpi[d].write();return a},this.writePublicKey=this.write,this.writeOld=function(){var a=this.writePublicKey();return String.fromCharCode(153)+c.writeNumber(a.length,2)+a},this.getKeyId=function(){var a=new e;return 4==this.version?a.read(this.getFingerprint().substr(12,8)):3==this.version&&a.read(this.mpi[0].write().substr(-8)),a},this.getFingerprint=function(){var a="";if(4==this.version)return a=this.writeOld(),g.hash.sha1(a);if(3==this.version){for(var b=g.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].toBytes();return g.hash.md5(a)}}}},{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56}],42:[function(a,b){var c=a("../type/keyid.js"),d=a("../util"),e=a("../type/mpi.js"),f=a("../enums.js"),g=a("../crypto");b.exports=function(){this.version=3,this.publicKeyId=new c,this.publicKeyAlgorithm="rsa_encrypt",this.sessionKey=null,this.sessionKeyAlgorithm="aes256",this.encrypted=[],this.read=function(a){this.version=a.charCodeAt(0),this.publicKeyId.read(a.substr(1)),this.publicKeyAlgorithm=f.read(f.publicKey,a.charCodeAt(9));var b=10,c=function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":return 1;case"elgamal":return 2;default:throw new Error("Invalid algorithm.")}}(this.publicKeyAlgorithm);this.encrypted=[];for(var d=0;c>d;d++){var g=new e;b+=g.read(a.substr(b)),this.encrypted.push(g)}},this.write=function(){var a=String.fromCharCode(this.version);a+=this.publicKeyId.write(),a+=String.fromCharCode(f.write(f.publicKey,this.publicKeyAlgorithm));for(var b=0;bo&&me;){var f=d.readSimpleLength(a.substr(e));e+=f.offset,this.read_sub_packet(a.substr(e,f.len)),e+=f.len}return e}var e=0;switch(this.version=a.charCodeAt(e++),this.version){case 3:5!=a.charCodeAt(e++)&&c.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(e-1));var f=e;this.signatureType=a.charCodeAt(e++),this.created=c.readDate(a.substr(e,4)),e+=4,this.signatureData=a.substring(f,e),this.issuerKeyId.read(a.substring(e,e+8)),e+=8,this.publicKeyAlgorithm=a.charCodeAt(e++),this.hashAlgorithm=a.charCodeAt(e++);break;case 4:this.signatureType=a.charCodeAt(e++),this.publicKeyAlgorithm=a.charCodeAt(e++),this.hashAlgorithm=a.charCodeAt(e++),e+=b.call(this,a.substr(e),!0),this.signatureData=a.substr(0,e),e+=b.call(this,a.substr(e),!1);break;default:throw new Error("Version "+version+" of the signature is unsupported.")}this.signedHashValue=a.substr(e,2),e+=2,this.signature=a.substr(e)},this.write=function(){return this.signatureData+c.writeNumber(0,2)+this.signedHashValue+this.signature},this.sign=function(a,b){var c=e.write(e.signature,this.signatureType),d=e.write(e.publicKey,this.publicKeyAlgorithm),g=e.write(e.hash,this.hashAlgorithm),h=String.fromCharCode(4);h+=String.fromCharCode(c),h+=String.fromCharCode(d),h+=String.fromCharCode(g),this.issuerKeyId=a.getKeyId(),h+=this.write_all_sub_packets(),this.signatureData=h;var i=this.calculateTrailer(),j=this.toSign(c,b)+this.signatureData+i,k=f.hash.digest(g,j);this.signedHashValue=k.substr(0,2),this.signature=f.signature.sign(g,d,a.mpi,j)},this.write_all_sub_packets=function(){var b=e.signatureSubpacket,d="",f="";if(null!==this.created&&(d+=a(b.signature_creation_time,c.writeDate(this.created))),null!==this.signatureExpirationTime&&(d+=a(b.signature_expiration_time,c.writeNumber(this.signatureExpirationTime,4))),null!==this.exportable&&(d+=a(b.exportable_certification,String.fromCharCode(this.exportable?1:0))),null!==this.trustLevel&&(f=String.fromCharCode(this.trustLevel)+String.fromCharCode(this.trustAmount),d+=a(b.trust_signature,f)),null!==this.regularExpression&&(d+=a(b.regular_expression,this.regularExpression)),null!==this.revocable&&(d+=a(b.revocable,String.fromCharCode(this.revocable?1:0))),null!==this.keyExpirationTime&&(d+=a(b.key_expiration_time,c.writeNumber(this.keyExpirationTime,4))),null!==this.preferredSymmetricAlgorithms&&(f=c.bin2str(this.preferredSymmetricAlgorithms),d+=a(b.preferred_symmetric_algorithms,f)),null!==this.revocationKeyClass&&(f=String.fromCharCode(this.revocationKeyClass),f+=String.fromCharCode(this.revocationKeyAlgorithm),f+=this.revocationKeyFingerprint,d+=a(b.revocation_key,f)),this.issuerKeyId.isNull()||(d+=a(b.issuer,this.issuerKeyId.write())),null!==this.notation)for(var g in this.notation)if(this.notation.hasOwnProperty(g)){var h=this.notation[g];f=String.fromCharCode(128),f+=String.fromCharCode(0),f+=String.fromCharCode(0),f+=String.fromCharCode(0),f+=c.writeNumber(g.length,2),f+=c.writeNumber(h.length,2),f+=g+h,d+=a(b.notation_data,f)}return null!==this.preferredHashAlgorithms&&(f=c.bin2str(this.preferredHashAlgorithms),d+=a(b.preferred_hash_algorithms,f)),null!==this.preferredCompressionAlgorithms&&(f=c.bin2str(this.preferredCompressionAlgorithms),d+=a(b.preferred_hash_algorithms,f)),null!==this.keyServerPreferences&&(f=c.bin2str(this.keyServerPreferences),d+=a(b.key_server_preferences,f)),null!==this.preferredKeyServer&&(d+=a(b.preferred_key_server,this.preferredKeyServer)),null!==this.isPrimaryUserID&&(d+=a(b.primary_user_id,String.fromCharCode(this.isPrimaryUserID?1:0))),null!==this.policyURI&&(d+=a(b.policy_uri,this.policyURI)),null!==this.keyFlags&&(f=c.bin2str(this.keyFlags),d+=a(b.key_flags,f)),null!==this.signersUserId&&(d+=a(b.signers_user_id,this.signersUserId)),null!==this.reasonForRevocationFlag&&(f=String.fromCharCode(this.reasonForRevocationFlag),f+=this.reasonForRevocationString,d+=a(b.reason_for_revocation,f)),null!==this.features&&(f=c.bin2str(this.features),d+=a(b.features,f)),null!==this.signatureTargetPublicKeyAlgorithm&&(f=String.fromCharCode(this.signatureTargetPublicKeyAlgorithm),f+=String.fromCharCode(this.signatureTargetHashAlgorithm),f+=this.signatureTargetHash,d+=a(b.signature_target,f)),null!==this.embeddedSignature&&(d+=a(b.embedded_signature,this.embeddedSignature.write())),d=c.writeNumber(d.length,2)+d},this.read_sub_packet=function(a){function b(a,b){this[a]=[];for(var c=0;c0&&4>d?k=1:17==d&&(k=2);for(var l=[],m=0,n=0;k>n;n++)l[n]=new g,m+=l[n].read(this.signature.substr(m));return this.verified=f.signature.verify(d,h,l,a.mpi,i+this.signatureData+j),this.verified},this.isExpired=function(){return this.signatureNeverExpires?!1:Date.now()>this.created.getTime()+1e3*this.signatureExpirationTime}}},{"../crypto":16,"../enums.js":27,"../type/keyid.js":53,"../type/mpi.js":54,"../util":56,"./packet.js":39}],47:[function(a,b){var c=(a("../util"),a("../crypto"));b.exports=function(){this.encrypted=null,this.modification=!1,this.packets=null,this.read=function(a){var b=a.charCodeAt(0);if(1!=b)throw new Error("Invalid packet version.");this.encrypted=a.substr(1)},this.write=function(){return String.fromCharCode(1)+this.encrypted},this.encrypt=function(a,b){var d=this.packets.write(),e=c.getPrefixRandom(a),f=e+e.charAt(e.length-2)+e.charAt(e.length-1),g=d;g+=String.fromCharCode(211),g+=String.fromCharCode(20),g+=c.hash.sha1(f+g),this.encrypted=c.cfb.encrypt(e,a,g,b,!1).substring(0,f.length+g.length)},this.decrypt=function(a,b){var d=c.cfb.decrypt(a,b,this.encrypted,!1);this.hash=c.hash.sha1(c.cfb.mdc(a,b,this.encrypted)+d.substring(0,d.length-20));var e=d.substr(d.length-20,20);if(this.hash!=e)throw new Error("Modification detected.");this.packets.read(d.substr(0,d.length-22))}}},{"../crypto":16,"../util":56}],48:[function(a,b){var c=a("../type/s2k.js"),d=a("../enums.js"),e=a("../crypto");b.exports=function(){this.tag=3,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new c,this.read=function(a){this.version=a.charCodeAt(0);var b=d.read(d.symmetric,a.charCodeAt(1)),c=this.s2k.read(a.substr(2)),e=c+2;e>4)+a},this.read=function(a){var b=0;switch(this.type=c.read(c.s2k,a.charCodeAt(b++)),this.algorithm=c.read(c.hash,a.charCodeAt(b++)),this.type){case"simple":break;case"salted":this.salt=a.substr(b,8),b+=8;break;case"iterated":this.salt=a.substr(b,8),b+=8,this.c=a.charCodeAt(b++);break;case"gnu":if("GNU"!=a.substr(b,3))throw new Error("Unknown s2k type.");b+=3;var d=1e3+a.charCodeAt(b++);if(1001!=d)throw new Error("Unknown s2k gnu protection mode.");this.type=d;break;default:throw new Error("Unknown s2k type.")}return b},this.write=function(){var a=String.fromCharCode(c.write(c.s2k,this.type));switch(a+=String.fromCharCode(c.write(c.hash,this.algorithm)),this.type){case"simple":break;case"salted":a+=this.salt;break;case"iterated":a+=this.salt,a+=String.fromCharCode(this.c)}return a},this.produce_key=function(a,b){function f(b,d){var f=c.write(c.hash,d.algorithm);switch(d.type){case"simple":return e.hash.digest(f,b+a);case"salted":return e.hash.digest(f,b+d.salt+a);case"iterated":var g=[],h=d.get_count();for(data=d.salt+a;g.length*data.lengthh&&(g=g.substr(0,h)),e.hash.digest(f,b+g)}}a=d.encode_utf8(a);for(var g="",h="";g.length<=b;)g+=f(h,this),h+=String.fromCharCode(0);return g.substr(0,b)}}},{"../crypto":16,"../enums.js":27,"../util":56}],56:[function(a,b){var c=a("../config");b.exports={readNumber:function(a){for(var b=0,c=0;cd;d++)c+=String.fromCharCode(a>>8*(b-d-1)&255);return c},readDate:function(a){var b=this.readNumber(a),c=new Date;return c.setTime(1e3*b),c},writeDate:function(a){var b=Math.round(a.getTime()/1e3);return this.writeNumber(b,4)},emailRegEx:/^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/,hexdump:function(a){for(var b,c=[],d=a.length,e=0,f=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(" "+b),f++,f%32==0&&c.push("\n ")}return c.join("")},hexstrdump:function(a){if(null==a)return"";for(var b,c=[],d=a.length,e=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},hex2bin:function(a){for(var b="",c=0;ce;){for(b=a[e++].toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},encode_utf8:function(a){return unescape(encodeURIComponent(a))},decode_utf8:function(a){try{return decodeURIComponent(escape(a))}catch(b){return a}},bin2str:function(a){for(var b=[],c=0;c=0;d--)c[d]>>=b%8,d>0&&(c[d]|=c[d-1]<<8-b%8&255);return util.bin2str(c)},get_hashAlgorithmString:function(a){switch(a){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}}},{"../config":3}]},{},[]); \ No newline at end of file diff --git a/src/cleartext.js b/src/cleartext.js index 544a2c51..34924849 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -15,12 +15,18 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module cleartext */ +/** + * @requires config + * @requires encoding/armor + * @requires enums + * @requires packet + * @module cleartext + */ -var config = require('./config'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); +var config = require('./config'), + packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'); /** * @class @@ -127,6 +133,7 @@ CleartextMessage.prototype.armor = function() { * reads an OpenPGP cleartext signed message and returns a CleartextMessage object * @param {String} armoredText text to be parsed * @return {module:cleartext~CleartextMessage} new cleartext message object + * @static */ function readArmored(armoredText) { var input = armor.decode(armoredText); diff --git a/src/config/config.js b/src/config/config.js index dc6a9712..8f38163e 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -15,48 +15,33 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module config/config */ +/** + * This object contains configuration values. + * @requires enums + * @property {Integer} prefer_hash_algorithm + * @property {Integer} encryption_cipher + * @property {Integer} compression + * @property {Boolean} show_version + * @property {Boolean} show_comment + * @property {Boolean} integrity_protect + * @property {String} keyserver + * @property {Boolean} debug If enabled, debug messages will be printed + * @module config/config + */ var enums = require('../enums.js'); -/** - * - * This object contains configuration values and implements - * storing and retrieving configuration them from HTML5 local storage. - * - * This object can be accessed after calling openpgp.init() - * using openpgp.config - * Stored config parameters can be accessed using - * openpgp.config.config - * @class - * @classdesc Implementation of the GPG4Browsers config object - */ -var config = function() { - /** - * @property {Integer} prefer_hash_algorithm - * @property {Integer} encryption_cipher - * @property {Integer} compression - * @property {Boolean} show_version - * @property {Boolean} show_comment - * @property {Boolean} integrity_protect - * @property {String} keyserver - */ - this.prefer_hash_algorithm = enums.hash.sha256; - this.encryption_cipher = enums.symmetric.aes256; - this.compression = enums.compression.zip; - this.show_version = true; - this.show_comment = true; - this.integrity_protect = true; - this.keyserver = "keyserver.linux.it"; // "pgp.mit.edu:11371" +module.exports = { + prefer_hash_algorithm: enums.hash.sha256, + encryption_cipher: enums.symmetric.aes256, + compression: enums.compression.zip, + show_version: true, + show_comment: true, + integrity_protect: true, + keyserver: "keyserver.linux.it", // "pgp.mit.edu:11371" - this.versionstring = "OpenPGP.js VERSION"; - this.commentstring = "http://openpgpjs.org"; - - /** - * If enabled, debug messages will be printed - */ - this.debug = false; + versionstring: "OpenPGP.js VERSION", + commentstring: "http://openpgpjs.org", + debug: false }; - -module.exports = new config(); diff --git a/src/config/config.localStorage.js b/src/config/localStorage.js similarity index 69% rename from src/config/config.localStorage.js rename to src/config/localStorage.js index f7b69d1a..08de17f8 100644 --- a/src/config/config.localStorage.js +++ b/src/config/localStorage.js @@ -1,12 +1,10 @@ -/** @module config/config_localStorage */ +/** + * This object storing and retrieving configuration from HTML5 local storage. + * @module config/localStorage + */ /** - * - * This object storing and retrieving configuration from HTML5 local storage. - * - * This object can be accessed after calling openpgp.init() - * @class - * @classdesc Implementation of the config handler for localstorage + * @constructor */ module.exports = function () { @@ -15,7 +13,7 @@ module.exports = function () { * and initializes the object config. * if config is null the default config will be used */ - function read() { + this.read = function () { var cf = JSON.parse(window.localStorage.getItem("config")); if (cf === null) { this.config = this.default_config; @@ -27,10 +25,7 @@ module.exports = function () { /** * Writes the config to HTML5 local storage */ - function write() { + this.write = function () { window.localStorage.setItem("config", JSON.stringify(this.config)); } - - this.read = read; - this.write = write; } diff --git a/src/crypto/cfb.js b/src/crypto/cfb.js index 7fc73cc0..a2147782 100644 --- a/src/crypto/cfb.js +++ b/src/crypto/cfb.js @@ -15,40 +15,28 @@ * materials provided with the application or distribution. */ -/** @module crypto/cfb */ +/** + * @requires crypto/cipher + * @requires util + * @module crypto/cfb + */ var util = require('../util'), cipher = require('./cipher'); module.exports = { - /** - * An array of bytes, that is integers with values from 0 to 255 - * @typedef {(Array|Uint8Array)} openpgp_byte_array - */ - - /** - * Block cipher function - * @callback openpgp_block_cipher_fn - * @param {openpgp_byte_array} block A block to perform operations on - * @param {openpgp_byte_array} key to use in encryption/decryption - * @return {openpgp_byte_array} Encrypted/decrypted block - */ - - - // -------------------------------------- /** * This function encrypts a given with the specified prefixrandom * using the specified blockcipher to encrypt a message * @param {String} prefixrandom random bytes of block_size length provided * as a string to be used in prefixing the data - * @param {openpgp_block_cipher_fn} blockcipherfn the algorithm encrypt function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used + * @param {String} cipherfn the algorithm cipher class to encrypt + * data in one block_size encryption, @see module:crypto/cipher. * @param {String} plaintext data to be encrypted provided as a string - * @param {openpgp_byte_array} key key to be used to encrypt the data. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the + * @param {String} key binary string representation of key to be used to encrypt the plaintext. + * This will be passed to the cipherfn + * @param {Boolean} resync a boolean value specifying if a resync of the * IV should be used or not. The encrypteddatapacket uses the * "old" style with a resync. Encryption within an * encryptedintegrityprotecteddata packet is not resyncing the IV. @@ -151,9 +139,10 @@ module.exports = { /** * Decrypts the prefixed data for the Modification Detection Code (MDC) computation - * @param {openpgp_block_cipher_fn} cipherfn.encrypt Cipher function to use - * @param {Integer} block_size Blocksize of the algorithm - * @param {openpgp_byte_array} key The key for encryption + * @param {String} cipherfn.encrypt Cipher function to use, + * @see module:crypto/cipher. + * @param {String} key binary string representation of key to be used to check the mdc + * This will be passed to the cipherfn * @param {String} ciphertext The encrypted data * @return {String} plaintext Data of D(ciphertext) with blocksize length +2 */ @@ -184,13 +173,12 @@ module.exports = { /** * This function decrypts a given plaintext using the specified * blockcipher to decrypt a message - * @param {openpgp_block_cipher_fn} blockcipherfn The algorithm _encrypt_ function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used - * @param {String} plaintext ciphertext to be decrypted provided as a string - * @param {openpgp_byte_array} key key to be used to decrypt the ciphertext. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the + * @param {String} cipherfn the algorithm cipher class to decrypt + * data in one block_size encryption, @see module:crypto/cipher. + * @param {String} key binary string representation of key to be used to decrypt the ciphertext. + * This will be passed to the cipherfn + * @param {String} ciphertext to be decrypted provided as a string + * @param {Boolean} resync a boolean value specifying if a resync of the * IV should be used or not. The encrypteddatapacket uses the * "old" style with a resync. Decryption within an * encryptedintegrityprotecteddata packet is not resyncing the IV. diff --git a/src/crypto/cipher/aes.js b/src/crypto/cipher/aes.js index 2898f7c0..a8f6e6cd 100644 --- a/src/crypto/cipher/aes.js +++ b/src/crypto/cipher/aes.js @@ -11,7 +11,10 @@ * materials provided with the application or distribution. */ -/** @module crypto/cipher/aes */ +/** + * @requires util + * @module crypto/cipher/aes + */ var util = require('../../util'); diff --git a/src/crypto/cipher/blowfish.js b/src/crypto/cipher/blowfish.js index 9e7a08d8..f6d2445d 100644 --- a/src/crypto/cipher/blowfish.js +++ b/src/crypto/cipher/blowfish.js @@ -3,7 +3,9 @@ * Originally written by nklein software (nklein.com) */ -/** @module crypto/cipher/blowfish */ +/** + * @module crypto/cipher/blowfish + */ /* * Javascript implementation based on Bruce Schneier's reference implementation. diff --git a/src/crypto/cipher/des.js b/src/crypto/cipher/des.js index 0653e55d..5cb2bf03 100644 --- a/src/crypto/cipher/des.js +++ b/src/crypto/cipher/des.js @@ -21,9 +21,9 @@ //des //this takes the key, the message, and whether to encrypt or decrypt -/** @module crypto/cipher/des */ - - +/** + * @module crypto/cipher/des + */ function des(keys, message, encrypt, mode, iv, padding) { @@ -402,6 +402,8 @@ function OriginalDes(key) { } module.exports = { + /** @static */ des: Des, + /** @static */ originalDes: OriginalDes } diff --git a/src/crypto/cipher/index.js b/src/crypto/cipher/index.js index 296ef984..99462457 100644 --- a/src/crypto/cipher/index.js +++ b/src/crypto/cipher/index.js @@ -1,10 +1,23 @@ +/** + * @requires crypto/cipher/aes + * @requires crypto/cipher/blowfish + * @requires crypto/cipher/cast5 + * @requires crypto/cipher/twofish + * @module crypto/cipher + */ + var desModule = require('./des.js'); module.exports = { + /** @see module:crypto/cipher/des.des */ des: desModule['des'], + /** @see module:crypto/cipher/des.originalDes */ originalDes: desModule['originalDes'], + /** @see module:crypto/cipher/cast5 */ cast5: require('./cast5.js'), + /** @see module:crypto/cipher/twofish */ twofish: require('./twofish.js'), + /** @see module:crypto/cipher/blowfish */ blowfish: require('./blowfish.js') } diff --git a/src/crypto/cipher/twofish.js b/src/crypto/cipher/twofish.js index c29a434f..5e99834f 100644 --- a/src/crypto/cipher/twofish.js +++ b/src/crypto/cipher/twofish.js @@ -18,7 +18,9 @@ * */ -/** @module crypto/cipher/twofish */ +/** + * @module crypto/cipher/twofish + */ diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 85db090f..5799cf2c 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -17,7 +17,13 @@ // The GPG4Browsers crypto interface -/** @module crypto/crypto */ +/** + * @requires crypto/cipher + * @requires crypto/public_key + * @requires crypto/random + * @requires type/mpi + * @module crypto/crypto + */ var random = require('./random.js'), cipher = require('./cipher'), @@ -213,6 +219,5 @@ module.exports = { */ generateSessionKey: function(algo) { return random.getRandomBytes(cipher[algo].keySize); - }, - + } }; diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js index 6561e283..f6b7a97c 100644 --- a/src/crypto/hash/index.js +++ b/src/crypto/hash/index.js @@ -1,12 +1,23 @@ +/** + * @requires crypto/hash/sha + * @module crypto/hash + */ var sha = require('./sha.js'); module.exports = { + /** @see module:crypto/hash/md5 */ md5: require('./md5.js'), + /** @see module:crypto/hash/sha.sha1 */ sha1: sha.sha1, - sha256: sha.sha256, + /** @see module:crypto/hash/sha.sha224 */ sha224: sha.sha224, + /** @see module:crypto/hash/sha.sha256 */ + sha256: sha.sha256, + /** @see module:crypto/hash/sha.sha384 */ sha384: sha.sha384, + /** @see module:crypto/hash/sha.sha512 */ sha512: sha.sha512, + /** @see module:crypto/hash/ripe-md */ ripemd: require('./ripe-md.js'), /** @@ -74,5 +85,4 @@ module.exports = { throw new Error('Invalid hash algorithm.'); } } - } diff --git a/src/crypto/hash/md5.js b/src/crypto/hash/md5.js index 06648aee..07f70adc 100644 --- a/src/crypto/hash/md5.js +++ b/src/crypto/hash/md5.js @@ -12,11 +12,18 @@ * warranty of any kind. */ -/** @module crypto/hash/md5 */ +/** + * @requires util + * @module crypto/hash/md5 + */ -var util = require('../../util/util.js'); +var util = require('../../util'); -function MD5(entree) { +/** + * MD5 hash + * @param {String} entree string to hash + */ +module.exports = function (entree) { var hex = md5(entree); var bin = util.hex2bin(hex); return bin; @@ -208,5 +215,3 @@ if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { return (msw << 16) | (lsw & 0xFFFF); } } - -module.exports = MD5 diff --git a/src/crypto/hash/ripe-md.js b/src/crypto/hash/ripe-md.js index a21e6288..d93ba764 100644 --- a/src/crypto/hash/ripe-md.js +++ b/src/crypto/hash/ripe-md.js @@ -20,7 +20,9 @@ /* Modified by Recurity Labs GmbH */ -/** @module crypto/hash/ripe-md */ +/** + * @module crypto/hash/ripe-md + */ var RMDsize = 160; var X = new Array(); diff --git a/src/crypto/hash/sha.js b/src/crypto/hash/sha.js index 838e8e3d..f77b7efb 100644 --- a/src/crypto/hash/sha.js +++ b/src/crypto/hash/sha.js @@ -21,7 +21,9 @@ * - str_sha512 */ -/** @module crypto/hash/sha */ +/** + * @module crypto/hash/sha + */ var jsSHA = (function() { @@ -1094,23 +1096,28 @@ var jsSHA = (function() { }()); module.exports = { + /** SHA1 hash */ sha1: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-1", "ASCII"); }, + /** SHA224 hash */ sha224: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-224", "ASCII"); }, + /** SHA256 hash */ sha256: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-256", "ASCII"); }, + /** SHA384 hash */ sha384: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-384", "ASCII"); }, + /** SHA512 hash */ sha512: function(str) { var shaObj = new jsSHA(str, "ASCII"); return shaObj.getHash("SHA-512", "ASCII"); diff --git a/src/crypto/index.js b/src/crypto/index.js index 231e6e22..ac1ddb79 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -1,10 +1,21 @@ +/** + * @see module:crypto/crypto + * @module crypto + */ module.exports = { + /** @see module:crypto/cipher */ cipher: require('./cipher'), + /** @see module:crypto/hash */ hash: require('./hash'), + /** @see module:crypto/cfb */ cfb: require('./cfb.js'), + /** @see module:crypto/public_key */ publicKey: require('./public_key'), + /** @see module:crypto/signature */ signature: require('./signature.js'), + /** @see module:crypto/random */ random: require('./random.js'), + /** @see module:crypto/pkcs1 */ pkcs1: require('./pkcs1.js') } diff --git a/src/crypto/pkcs1.js b/src/crypto/pkcs1.js index f4826df6..86838366 100644 --- a/src/crypto/pkcs1.js +++ b/src/crypto/pkcs1.js @@ -15,7 +15,15 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module crypto/pkcs1 */ +/** + * PKCS1 encoding + * @requires crypto/crypto + * @requires crypto/hash + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/pkcs1 + */ /** * ASN1 object identifiers for hashes (See RFC4880 5.2.2) @@ -24,8 +32,8 @@ hash_headers = new Array(); hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 ]; -hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; +hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 ]; @@ -39,7 +47,6 @@ hash_headers[11] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x00, 0x04, 0x1C ]; - var crypto = require('./crypto.js'), random = require('./random.js'), util = require('../util'), @@ -82,7 +89,7 @@ module.exports = { while (message.charCodeAt(i) != 0 && message.length > i) i++; return message.substring(i + 1, message.length); - }, + } }, emsa: { diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index 668a04ac..d488e3dc 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -17,12 +17,19 @@ // // A Digital signature algorithm implementation -/** @module crypto/public_key/dsa */ +/** + * @requires crypto/hash + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/dsa + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), hashModule = require('../hash'), - util = require('../../util'); + util = require('../../util'), + config = require('../../config'); function DSA() { // s1 = ((g**s) mod p) mod q @@ -45,7 +52,7 @@ function DSA() { } function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; + var usersetting = config.prefer_hash_algorithm; /* * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash diff --git a/src/crypto/public_key/elgamal.js b/src/crypto/public_key/elgamal.js index 852149b3..4cc3a686 100644 --- a/src/crypto/public_key/elgamal.js +++ b/src/crypto/public_key/elgamal.js @@ -17,7 +17,12 @@ // // ElGamal implementation -/** @module crypto/public_key/elgamal */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/elgamal + */ var BigInteger = require('./jsbn.js'), random = require('../random.js'), diff --git a/src/crypto/public_key/index.js b/src/crypto/public_key/index.js index fa852466..beafaf9f 100644 --- a/src/crypto/public_key/index.js +++ b/src/crypto/public_key/index.js @@ -1,5 +1,14 @@ +/** + * @requires crypto/public_key/dsa + * @requires crypto/public_key/elgamal + * @requires crypto/public_key/rsa + * @module crypto/public_key + */ module.exports = { + /** @see module:crypto/public_key/rsa */ rsa: require('./rsa.js'), + /** @see module:crypto/public_key/elgamal */ elgamal: require('./elgamal.js'), + /** @see module:crypto/public_key/dsa */ dsa: require('./dsa.js') } diff --git a/src/crypto/public_key/jsbn.js b/src/crypto/public_key/jsbn.js index 81f68195..845fd44a 100644 --- a/src/crypto/public_key/jsbn.js +++ b/src/crypto/public_key/jsbn.js @@ -32,7 +32,10 @@ */ -/** @module crypto/public_key/jsbn */ +/** + * @requires util + * @module crypto/public_key/jsbn + */ var util = require('../../util'); diff --git a/src/crypto/public_key/rsa.js b/src/crypto/public_key/rsa.js index e2eb1a7d..3338238e 100644 --- a/src/crypto/public_key/rsa.js +++ b/src/crypto/public_key/rsa.js @@ -17,7 +17,12 @@ // // RSA implementation -/** @module crypto/public_key/rsa */ +/** + * @requires crypto/public_key/jsbn + * @requires crypto/random + * @requires util + * @module crypto/public_key/rsa + */ var BigInteger = require('./jsbn.js'), util = require('../../util'), diff --git a/src/crypto/random.js b/src/crypto/random.js index f87fcf2c..774acda3 100644 --- a/src/crypto/random.js +++ b/src/crypto/random.js @@ -17,7 +17,10 @@ // The GPG4Browsers crypto interface -/** @module crypto/random */ +/** + * @requires type/mpi + * @module crypto/random + */ var type_mpi = require('../type/mpi.js'); diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 1ebc4dfb..5d51c374 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -1,4 +1,8 @@ -/** @module crypto/signature */ +/** + * @requires crypto/hash + * @requires crypto/pkcs1 + * @requires crypto/public_key + * @module crypto/signature */ var publicKey = require('./public_key'), pkcs1 = require('./pkcs1.js'), diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 9d852398..11efddae 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -15,11 +15,16 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module encoding/armor */ +/** + * @requires encoding/base64 + * @requires enums + * @requires config + * @module encoding/armor + */ -var base64 = require('./base64.js'); -var enums = require('../enums.js'); -var config = require('../config'); +var base64 = require('./base64.js'), + enums = require('../enums.js'), + config = require('../config'); /** * Finds out which Ascii Armoring type is used. This is an internal function @@ -32,7 +37,7 @@ var config = require('../config'); * 5 = PRIVATE KEY BLOCK * null = unknown */ -function get_type(text) { +function getType(text) { var reHeader = /^-----([^-]+)-----$\n/m; var header = text.match(reHeader); @@ -85,7 +90,7 @@ function get_type(text) { * @version 2011-12-16 * @returns {String} The header information */ -function armor_addheader() { +function addheader() { var result = ""; if (config.show_version) { result += "Version: " + config.versionstring + '\r\n'; @@ -201,7 +206,7 @@ function createcrc24(input) { * or an object with attribute "headers" containing the headers and * and an attribute "body" containing the body. */ -function split_headers(text) { +function splitHeaders(text) { var reEmptyLine = /^[\t ]*\n/m; var headers = ""; var body = text; @@ -223,7 +228,7 @@ function split_headers(text) { * or an object with attribute "body" containing the body * and an attribute "checksum" containing the checksum. */ -function split_checksum(text) { +function splitChecksum(text) { var reChecksumStart = /^=/m; var body = text; var checksum = ""; @@ -244,13 +249,14 @@ function split_checksum(text) { * @param {String} text OpenPGP armored message * @returns {Object} An object with attribute "text" containing the message text, * an attribute "data" containing the bytes and "type" for the ASCII armor type + * @static */ function dearmor(text) { var reSplit = /^-----[^-]+-----$\n/m; text = text.replace(/\r/g, ''); - var type = get_type(text); + var type = getType(text); if (!type) { throw new Error('Unknow ASCII armor type'); } @@ -269,8 +275,8 @@ function dearmor(text) { } if (type != 2) { - var msg = split_headers(splittext[indexBase]); - var msg_sum = split_checksum(msg.body); + var msg = splitHeaders(splittext[indexBase]); + var msg_sum = splitChecksum(msg.body); result = { data: base64.decode(msg_sum.body), @@ -280,9 +286,9 @@ function dearmor(text) { checksum = msg_sum.checksum; } else { // Reverse dash-escaping for msg and remove trailing whitespace at end of line - var msg = split_headers(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); - var sig = split_headers(splittext[indexBase + 1].replace(/^- /mg, '')); - var sig_sum = split_checksum(sig.body); + var msg = splitHeaders(splittext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); + var sig = splitHeaders(splittext[indexBase + 1].replace(/^- /mg, '')); + var sig_sum = splitChecksum(sig.body); result = { text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"), @@ -311,20 +317,21 @@ function dearmor(text) { * @param {Integer} partindex * @param {Integer} parttotal * @returns {String} Armored text + * @static */ function armor(messagetype, body, partindex, parttotal) { var result = ""; switch (messagetype) { case enums.armor.multipart_section: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; break; case enums.armor.mutlipart_last: result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n"; @@ -334,28 +341,28 @@ function armor(messagetype, body, partindex, parttotal) { result += "Hash: " + body.hash + "\r\n\r\n"; result += body.text.replace(/\n-/g, "\n- -"); result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body.data); result += "\r\n=" + getCheckSum(body.data) + "\r\n"; result += "-----END PGP SIGNATURE-----\r\n"; break; case enums.armor.message: result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP MESSAGE-----\r\n"; break; case enums.armor.public_key: result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; break; case enums.armor.private_key: result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += armor_addheader(); + result += addheader(); result += base64.encode(body); result += "\r\n=" + getCheckSum(body) + "\r\n"; result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; diff --git a/src/encoding/base64.js b/src/encoding/base64.js index a77249c4..e88b9d14 100644 --- a/src/encoding/base64.js +++ b/src/encoding/base64.js @@ -11,10 +11,18 @@ * provided with the application or distribution. */ -/** @module encoding/base64 */ +/** + * @module encoding/base64 + */ var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +/** + * Convert binary string to radix-64 + * @param {String} t binary string to convert + * @returns {string} radix-64 version of input string + * @static + */ function s2r(t) { var a, c, n; var r = '', @@ -62,6 +70,12 @@ function s2r(t) { return r; } +/** + * Convert radix-64 to binary string + * @param {String} t radix-64 string to convert + * @returns {string} binary version of input string + * @static + */ function r2s(t) { var c, n; var r = '', diff --git a/src/enums.js b/src/enums.js index b52bfd68..ccb995dd 100644 --- a/src/enums.js +++ b/src/enums.js @@ -1,9 +1,12 @@ -/** @module enums */ +/** + * @module enums + */ module.exports = { /** A string to key specifier type * @enum {Integer} + * @readonly */ s2k: { simple: 0, @@ -14,6 +17,7 @@ module.exports = { /** RFC4880, section 9.1 * @enum {Integer} + * @readonly */ publicKey: { rsa_encrypt_sign: 1, @@ -25,6 +29,7 @@ module.exports = { /** RFC4880, section 9.2 * @enum {Integer} + * @readonly */ symmetric: { plaintext: 0, @@ -41,6 +46,7 @@ module.exports = { /** RFC4880, section 9.3 * @enum {Integer} + * @readonly */ compression: { uncompressed: 0, @@ -53,6 +59,7 @@ module.exports = { /** RFC4880, section 9.4 * @enum {Integer} + * @readonly */ hash: { md5: 1, @@ -64,9 +71,9 @@ module.exports = { sha224: 11 }, - /** A list of packet types and numeric tags associated with them. * @enum {Integer} + * @readonly */ packet: { public_key_encrypted_session_key: 1, @@ -88,9 +95,9 @@ module.exports = { modification_detection_code: 19 }, - /** Data types in the literal packet * @enum {Integer} + * @readonly */ literal: { /** Binary data 'b' */ @@ -104,41 +111,42 @@ module.exports = { /** One pass signature packet type * @enum {Integer} + * @readonly */ signature: { /** 0x00: Signature of a binary document. */ binary: 0, - /** 0x01: Signature of a canonical text document. + /** 0x01: Signature of a canonical text document.
      * Canonicalyzing the document by converting line endings. */ text: 1, - /** 0x02: Standalone signature. + /** 0x02: Standalone signature.
      * This signature is a signature of only its own subpacket contents. * It is calculated identically to a signature over a zero-lengh * binary document. Note that it doesn't make sense to have a V3 * standalone signature. */ standalone: 2, - /** 0x10: Generic certification of a User ID and Public-Key packet. + /** 0x10: Generic certification of a User ID and Public-Key packet.
      * The issuer of this certification does not make any particular * assertion as to how well the certifier has checked that the owner * of the key is in fact the person described by the User ID. */ cert_generic: 16, - /** 0x11: Persona certification of a User ID and Public-Key packet. + /** 0x11: Persona certification of a User ID and Public-Key packet.
      * The issuer of this certification has not done any verification of * the claim that the owner of this key is the User ID specified. */ cert_persona: 17, - /** 0x12: Casual certification of a User ID and Public-Key packet. + /** 0x12: Casual certification of a User ID and Public-Key packet.
      * The issuer of this certification has done some casual * verification of the claim of identity. */ cert_casual: 18, - /** 0x13: Positive certification of a User ID and Public-Key packet. + /** 0x13: Positive certification of a User ID and Public-Key packet.
      * The issuer of this certification has done substantial - * verification of the claim of identity. - * + * verification of the claim of identity.
      + *
      * Most OpenPGP implementations make their "key signatures" as 0x10 * certifications. Some implementations can issue 0x11-0x13 * certifications, but few differentiate between the types. */ cert_positive: 19, - /** 0x30: Certification revocation signature + /** 0x30: Certification revocation signature
      * This signature revokes an earlier User ID certification signature * (signature class 0x10 through 0x13) or direct-key signature * (0x1F). It should be issued by the same key that issued the @@ -147,7 +155,7 @@ module.exports = { * revokes, and should have a later creation date than that * certificate. */ cert_revocation: 48, - /** 0x18: Subkey Binding Signature + /** 0x18: Subkey Binding Signature
      * This signature is a statement by the top-level signing key that * indicates that it owns the subkey. This signature is calculated * directly on the primary key and subkey, and not on any User ID or @@ -156,12 +164,12 @@ module.exports = { * contains a 0x19 signature made by the signing subkey on the * primary key and subkey. */ subkey_binding: 24, - /** 0x19: Primary Key Binding Signature + /** 0x19: Primary Key Binding Signature
      * This signature is a statement by a signing subkey, indicating * that it is owned by the primary key and subkey. This signature * is calculated the same way as a 0x18 signature: directly on the - * primary key and subkey, and not on any User ID or other packets. - + * primary key and subkey, and not on any User ID or other packets.
      + *
      * When a signature is made over a key, the hash data starts with the * octet 0x99, followed by a two-octet length of the key, and then body * of the key packet. (Note that this is an old-style packet header for @@ -170,7 +178,7 @@ module.exports = { * the subkey using the same format as the main key (also using 0x99 as * the first octet). */ key_binding: 25, - /** 0x1F: Signature directly on a key + /** 0x1F: Signature directly on a key
      * This signature is calculated directly on a key. It binds the * information in the Signature subpackets to the key, and is * appropriate to be used for subpackets that provide information @@ -179,26 +187,27 @@ module.exports = { * about the key itself, rather than the binding between a key and a * name. */ key: 31, - /** 0x20: Key revocation signature + /** 0x20: Key revocation signature
      * The signature is calculated directly on the key being revoked. A * revoked key is not to be used. Only revocation signatures by the * key being revoked, or by an authorized revocation key, should be * considered valid revocation signatures.a */ key_revocation: 32, - /** 0x28: Subkey revocation signature + /** 0x28: Subkey revocation signature
      * The signature is calculated directly on the subkey being revoked. * A revoked subkey is not to be used. Only revocation signatures * by the top-level signature key that is bound to this subkey, or * by an authorized revocation key, should be considered valid - * revocation signatures. + * revocation signatures.
      + *
      * Key revocation signatures (types 0x20 and 0x28) * hash only the key being revoked. */ subkey_revocation: 40, - /** 0x40: Timestamp signature. + /** 0x40: Timestamp signature.
      * This signature is only meaningful for the timestamp contained in * it. */ timestamp: 64, - /** 0x50: Third-Party Confirmation signature. + /** 0x50: Third-Party Confirmation signature.
      * This signature is a signature over some other OpenPGP Signature * packet(s). It is analogous to a notary seal on the signed data. * A third-party signature SHOULD include Signature Target @@ -211,6 +220,7 @@ module.exports = { /** Signature subpacket type * @enum {Integer} + * @readonly */ signatureSubpacket: { signature_creation_time: 2, @@ -241,28 +251,30 @@ module.exports = { /** Key flags * @enum {Integer} + * @readonly */ keyFlags: { - // 0x01 - This key may be used to certify other keys. + /** 0x01 - This key may be used to certify other keys. */ certify_keys: 1, - // 0x02 - This key may be used to sign data. + /** 0x02 - This key may be used to sign data. */ sign_data: 2, - // 0x04 - This key may be used to encrypt communications. + /** 0x04 - This key may be used to encrypt communications. */ encrypt_communication: 4, - // 0x08 - This key may be used to encrypt storage. + /** 0x08 - This key may be used to encrypt storage. */ encrypt_storage: 8, - // 0x10 - The private component of this key may have been split - // by a secret-sharing mechanism. + /** 0x10 - The private component of this key may have been split + * by a secret-sharing mechanism. */ split_private_key: 16, - // 0x20 - This key may be used for authentication. + /** 0x20 - This key may be used for authentication. */ authentication: 32, - // 0x80 - The private component of this key may be in the - // possession of more than one person. + /** 0x80 - The private component of this key may be in the + * possession of more than one person. */ shared_private_key: 128 }, /** Key status * @enum {Integer} + * @readonly */ keyStatus: { invalid: 0, @@ -274,6 +286,7 @@ module.exports = { /** Armor type * @enum {Integer} + * @readonly */ armor: { multipart_section: 0, diff --git a/src/index.js b/src/index.js index fc469a92..d6709e6c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,39 @@ module.exports = require('./openpgp.js'); + module.exports.key = require('./key.js'); module.exports.message = require('./message.js'); module.exports.cleartext = require('./cleartext.js'); -module.exports.util = require('./util'); +/** + * @see module:util/util + * @module util + */ +module.exports.util = require('./util/util.js'); module.exports.packet = require('./packet'); +/** + * @see module:type/mpi + * @module mpi + */ module.exports.mpi = require('./type/mpi.js'); +/** + * @see module:type/s2k + * @module s2k + */ module.exports.s2k = require('./type/s2k.js'); +/** + * @see module:type/keyid + * @module keyid + */ module.exports.keyid = require('./type/keyid.js'); +/** + * @see module:encoding/armor + * @module armor + */ module.exports.armor = require('./encoding/armor.js'); module.exports.enums = require('./enums.js'); -module.exports.config = require('./config'); +/** + * @see module:config/config + * @module config + */ +module.exports.config = require('./config/config.js'); module.exports.crypto = require('./crypto'); diff --git a/src/key.js b/src/key.js index 44afe303..11b4c9a2 100644 --- a/src/key.js +++ b/src/key.js @@ -15,12 +15,18 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module key */ +/** + * @requires config + * @requires encoding/armor + * @requires enums + * @requires packet + * @module key + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'); /** * @class @@ -664,6 +670,7 @@ SubKey.prototype.verify = function(primaryKey) { * Reads an OpenPGP armored text and returns one or multiple key objects * @param {String} armoredText text to be parsed * @return {{keys: Array, err: (Array|null)}} result object with key and error arrays + * @static */ function readArmored(armoredText) { var result = {}; @@ -705,6 +712,7 @@ function readArmored(armoredText) { * @param {String} userId assumes already in form of "User Name " * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {module:key~Key} + * @static */ function generate(keyType, numBits, userId, passphrase) { var packetlist = new packet.list(); diff --git a/src/keyring/keyring.js b/src/keyring/keyring.js index b0a1cbbc..22f33db3 100644 --- a/src/keyring/keyring.js +++ b/src/keyring/keyring.js @@ -15,36 +15,55 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/keyring */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/keyring + */ var openpgp = require('openpgp'); /** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * Callback to check if a key matches the input + * @callback module:keyring/keyring.checkCallback + * @param {String} input input to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the input matches the specified key */ -module.exports = function() { - this.keys = []; + +/** + * Initialization routine for the keyring. This method reads the + * keyring from HTML5 local storage and initializes this instance. + * @constructor + * @param {class} [storeHandler] class implementing load() and store() methods + */ +module.exports = function(storeHandler) { + if (!storeHandler) { + storeHandler = new (require('./localstore.js'))(); + } + this.storeHandler = storeHandler; + this.keys = this.storeHandler.load(); /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Calls the storeHandler to save the keys */ - this.init = function (storeHandler) { - if (!storeHandler) { - var localstore = require('./localstore.js'); - storeHandler = new localstore(); - } - this.storeHandler = storeHandler; - this.keys = []; - this.storeHandler.init(this.keys); - } - this.store = function () { this.storeHandler.store(this.keys); - } + }; + /** + * Clear the keyring - erase all the keys + */ + this.clear = function() { + this.keys = []; + }; + + /** + * Checks a key to see if it matches the specified email address + * @param {String} email email address to search for + * @param {module:key~Key} key The key to be checked. + * @return {Boolean} True if the email address is defined in the specified key + */ function emailCheck(email, key) { email = email.toLowerCase(); var keyEmails = key.getUserIds(); @@ -58,6 +77,13 @@ module.exports = function() { return false; } + /** + * Checks a key to see if it matches the specified keyid + * @param {String} id hex string keyid to search for + * @param {module:key~Key} key the key to be checked. + * @return {Boolean} true if the email address is defined in the specified key + * @inner + */ function idCheck(id, key) { var keyids = key.getKeyIds(); for (var i = 0; i < keyids.length; i++) { @@ -68,6 +94,14 @@ module.exports = function() { return false; } + /** + * searches all public keys in the keyring matching the address or address part of the user ids + * @param {Array} keys array of keys to search + * @param {module:keyring/keyring.checkCallback} identityFunction callback function which checks for a match + * @param {String} identityInput input to check against + * @param {module:enums.packet} keyType packet types of keys to check + * @return {Array} array of keys which match + */ function checkForIdentityAndKeyTypeMatch(keys, identityFunction, identityInput, keyType) { var results = []; for (var p = 0; p < keys.length; p++) { @@ -87,7 +121,6 @@ module.exports = function() { } return results; } - this.checkForIdentityAndKeyTypeMatch = checkForIdentityAndKeyTypeMatch; /** * searches all public keys in the keyring matching the address or address part of the user ids @@ -96,69 +129,62 @@ module.exports = function() { */ this.getPublicKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.public_key); - } + }; /** * Searches the keyring for a private key containing the specified email address * @param {String} email email address to search for * @return {Array} private keys found */ - function getPrivateKeyForAddress(email) { + this.getPrivateKeyForAddress = function (email) { return checkForIdentityAndKeyTypeMatch(this.keys, emailCheck, email, openpgp.enums.packet.secret_key); - } - this.getPrivateKeyForAddress = getPrivateKeyForAddress; + }; /** * Searches the keyring for public keys having the specified key id * @param {String} keyId provided as string of hex number (lowercase) * @return {Array} public keys found */ - function getKeysForKeyId(keyId) { - return this.checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); - } - this.getKeysForKeyId = getKeysForKeyId; + this.getKeysForKeyId = function (keyId) { + return checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, openpgp.enums.packet.public_key); + }; /** * Imports a key from an ascii armored message * @param {String} armored message to read the keys/key from */ - function importKey(armored) { + this.importKey = function (armored) { this.keys = this.keys.concat(openpgp.key.readArmored(armored).keys); return true; - } - this.importKey = importKey; + }; /** * returns the armored message representation of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the key object */ - function exportKey(index) { + this.exportKey = function (index) { return this.keys[index].armor(); - } - this.exportKey = exportKey; + }; /** - * Removes a public key from the public key keyring at the specified index + * Removes a public key from the public key keyring at the specified index * @param {Integer} index the index of the public key within the publicKeys array * @return {module:key~Key} The public key object which has been removed */ - function removeKey(index) { + this.removeKey = function (index) { var removed = this.keys.splice(index, 1); return removed; - } - this.removeKey = removeKey; + }; /** * returns the armored message representation of the public key portion of the key at key ring index * @param {Integer} index the index of the key within the array * @return {String} armored message representing the public key object */ - function exportPublicKey(index) { + this.exportPublicKey = function (index) { return this.keys[index].toPublic().armor(); - } - this.exportPublicKey = exportPublicKey; - + }; }; diff --git a/src/keyring/localstore.js b/src/keyring/localstore.js index 6c8be3ce..48e329a7 100644 --- a/src/keyring/localstore.js +++ b/src/keyring/localstore.js @@ -15,36 +15,36 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module keyring/localstore */ +/** + * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + * @requires openpgp + * @module keyring/localstore + */ var openpgp = require('openpgp'); -/** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. - */ module.exports = function () { /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). + * Load the keyring from HTML5 local storage and initializes this instance. + * @return {Array} array of keys retrieved from localstore */ - this.init = function (keys) { + this.load = function () { var armoredKeys = JSON.parse(window.localStorage.getItem("armoredKeys")); - if (armoredKeys !== null && armoredKeys.length === 0) { + var keys = []; + if (armoredKeys !== null && armoredKeys.length !== 0) { var key; for (var i = 0; i < armoredKeys.length; i++) { key = openpgp.key.readArmored(armoredKeys[i]); keys.push(key); } - } else { - this.keys = []; } + return keys; } /** * Saves the current state of the keyring to HTML5 local storage. * The privateKeys array and publicKeys array gets Stringified using JSON + * @param {Array} keys array of keys to save in localstore */ this.store = function (keys) { var armoredKeys = []; diff --git a/src/message.js b/src/message.js index ee79fc5d..cf4b5f38 100644 --- a/src/message.js +++ b/src/message.js @@ -15,14 +15,20 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module message */ +/** + * @requires config + * @requires crypto + * @requires encoding/armor + * @requires enums + * @requires packet + * @module message + */ -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); -var config = require('./config'); -var crypto = require('./crypto'); -var util = require('./util'); +var packet = require('./packet'), + enums = require('./enums.js'), + armor = require('./encoding/armor.js'), + config = require('./config'), + crypto = require('./crypto'); /** * @class @@ -261,6 +267,7 @@ Message.prototype.armor = function() { * reads an OpenPGP armored message and returns a message object * @param {String} armoredText text to be parsed * @return {module:message~Message} new message object + * @static */ function readArmored(armoredText) { //TODO how do we want to handle bad text? Exception throwing @@ -276,6 +283,7 @@ function readArmored(armoredText) { * creates new message object from text * @param {String} text * @return {module:message~Message} new message object + * @static */ function fromText(text) { var literalDataPacket = new packet.literal(); @@ -291,6 +299,7 @@ function fromText(text) { * creates new message object from binary data * @param {String} bytes * @return {module:message~Message} new message object + * @static */ function fromBinary(bytes) { var literalDataPacket = new packet.literal(); diff --git a/src/openpgp.js b/src/openpgp.js index fe56f8f1..9463d407 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -21,15 +21,23 @@ * for extending and developing on top of the base library. */ -/** @module openpgp */ +/** + * @requires cleartext + * @requires config + * @requires encoding/armor + * @requires enums + * @requires message + * @requires packet + * @module openpgp + */ -var armor = require('./encoding/armor.js'); -var packet = require('./packet'); -var enums = require('./enums.js'); -var config = require('./config'); -var message = require('./message.js'); -var cleartext = require('./cleartext.js'); -var key = require('./key.js'); +var armor = require('./encoding/armor.js'), + packet = require('./packet'), + enums = require('./enums.js'), + config = require('./config'), + message = require('./message.js'), + cleartext = require('./cleartext.js'), + key = require('./key.js'); /** @@ -37,6 +45,7 @@ var key = require('./key.js'); * @param {Array} keys array of keys, used to encrypt the message * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function encryptMessage(keys, text) { var msg = message.fromText(text); @@ -51,6 +60,7 @@ function encryptMessage(keys, text) { * @param {module:key~Key} privateKey private key with decrypted secret key data for signing * @param {String} text message as native JavaScript string * @return {String} encrypted ASCII armored message + * @static */ function signAndEncryptMessage(publicKeys, privateKey, text) { var msg = message.fromText(text); @@ -66,6 +76,7 @@ function signAndEncryptMessage(publicKeys, privateKey, text) { * @param {module:message~Message} message the message object with the encrypted data * @return {(String|null)} decrypted message as as native JavaScript string * or null if no literal data found + * @static */ function decryptMessage(privateKey, message) { message = message.decrypt(privateKey); @@ -80,6 +91,7 @@ function decryptMessage(privateKey, message) { * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * decrypted message as as native JavaScript string * with verified signatures or null if no literal data found + * @static */ function decryptAndVerifyMessage(privateKey, publicKeys, message) { var result = {}; @@ -97,6 +109,7 @@ function decryptAndVerifyMessage(privateKey, publicKeys, message) { * @param {Array} privateKeys private key with decrypted secret key data to sign cleartext * @param {String} text cleartext * @return {String} ASCII armored message + * @static */ function signClearMessage(privateKeys, text) { var cleartextMessage = new cleartext.CleartextMessage(text); @@ -110,6 +123,7 @@ function signClearMessage(privateKeys, text) { * @param {module:cleartext~CleartextMessage} message cleartext message object with signatures * @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}} * cleartext with status of verified signatures + * @static */ function verifyClearSignedMessage(publicKeys, message) { var result = {}; @@ -130,6 +144,7 @@ function verifyClearSignedMessage(publicKeys, message) { * @param {String} userId assumes already in form of "User Name " * @param {String} passphrase The passphrase used to encrypt the resulting private key * @return {Object} {key: Array, privateKeyArmored: Array, publicKeyArmored: Array} + * @static */ function generateKeyPair(keyType, numBits, userId, passphrase) { var result = {}; diff --git a/src/packet/all_packets.js b/src/packet/all_packets.js index 549c3332..8d7207c8 100644 --- a/src/packet/all_packets.js +++ b/src/packet/all_packets.js @@ -1,22 +1,43 @@ +/** + * @requires enums + * @module packet + */ var enums = require('../enums.js'); // This is pretty ugly, but browserify needs to have the requires explicitly written. + module.exports = { + /** @see module:packet/compressed */ compressed: require('./compressed.js'), + /** @see module:packet/sym_encrypted_integrity_protected */ sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'), + /** @see module:packet/public_key_encrypted_session_key */ public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'), + /** @see module:packet/sym_encrypted_session_key */ sym_encrypted_session_key: require('./sym_encrypted_session_key.js'), + /** @see module:packet/literal */ literal: require('./literal.js'), + /** @see module:packet/public_key */ public_key: require('./public_key.js'), + /** @see module:packet/symmetrically_encrypted */ symmetrically_encrypted: require('./symmetrically_encrypted.js'), + /** @see module:packet/marker */ marker: require('./marker.js'), + /** @see module:packet/public_subkey */ public_subkey: require('./public_subkey.js'), + /** @see module:packet/user_attribute */ user_attribute: require('./user_attribute.js'), + /** @see module:packet/one_pass_signature */ one_pass_signature: require('./one_pass_signature.js'), + /** @see module:packet/secret_key */ secret_key: require('./secret_key.js'), + /** @see module:packet/userid */ userid: require('./userid.js'), + /** @see module:packet/secret_subkey */ secret_subkey: require('./secret_subkey.js'), + /** @see module:packet/signature */ signature: require('./signature.js'), + /** @see module:packet/trust */ trust: require('./trust.js') } diff --git a/src/packet/compressed.js b/src/packet/compressed.js index 1441ace1..61ab6e10 100644 --- a/src/packet/compressed.js +++ b/src/packet/compressed.js @@ -15,38 +15,47 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/compressed */ +/** + * Implementation of the Compressed Data Packet (Tag 8)
      + *
      + * RFC4880 5.6: The Compressed Data packet contains compressed data. Typically, + * this packet is found as the contents of an encrypted packet, or following + * a Signature or One-Pass Signature packet, and contains a literal data packet. + * @requires compression/jxg + * @requires encoding/base64 + * @requires enums + * @module packet/compressed + */ var enums = require('../enums.js'), JXG = require('../compression/jxg.js'), base64 = require('../encoding/base64.js'); /** - * @class - * @classdesc Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. + * @constructor */ -module.exports = function packet_compressed() { - /** @type {module:packet/packetlist} */ - this.packets; - /** @type {compression} */ +module.exports = function () { + /** + * List of packets + * @type {module:packet/packetlist} + */ + this.packets = null; + /** + * Compression algorithm + * @type {compression} + */ this.algorithm = 'uncompressed'; + /** + * Compressed packet data + * @type {String} + */ this.compressed = null; /** * Parsing function for the packet. - * @param {String} input Payload of a tag 8 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of - * input at position - * @return {module:packet/compressed} Object representation + * @param {String} bytes Payload of a tag 8 packet */ this.read = function(bytes) { // One octet that gives the algorithm used to compress the packet. @@ -60,6 +69,10 @@ module.exports = function packet_compressed() { + /** + * Return the compressed packet. + * @return {String} binary compressed packet + */ this.write = function() { if (this.compressed == null) this.compress(); @@ -71,7 +84,6 @@ module.exports = function packet_compressed() { /** * Decompression method for decompressing the compressed data * read by read_packet - * @return {String} The decompressed data */ this.decompress = function() { var decompressed; @@ -128,9 +140,6 @@ module.exports = function packet_compressed() { /** * Compress the packet data (member decompressedData) - * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 - * @param {String} data Data to be compressed - * @return {String} The compressed data stored in attribute compressedData */ this.compress = function() { switch (this.algorithm) { diff --git a/src/packet/index.js b/src/packet/index.js index 0ca15e25..4396464c 100644 --- a/src/packet/index.js +++ b/src/packet/index.js @@ -1,7 +1,7 @@ var enums = require('../enums.js'); module.exports = { - list: require('./packetlist.js'), + list: require('./packetlist.js') }; var packets = require('./all_packets.js'); diff --git a/src/packet/literal.js b/src/packet/literal.js index fa2206e0..a9455eae 100644 --- a/src/packet/literal.js +++ b/src/packet/literal.js @@ -15,19 +15,23 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/literal */ +/** + * Implementation of the Literal Data Packet (Tag 11)
      + *
      + * RFC4880 5.9: A Literal Data packet contains the body of a message; data that + * is not to be further interpreted. + * @requires enums + * @requires util + * @module packet/literal + */ var util = require('../util'), enums = require('../enums.js'); /** - * @class - * @classdesc Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. + * @constructor */ -module.exports = function packet_literal() { +module.exports = function () { this.format = 'utf8'; // default format for literal data packets this.data = ''; // literal data representation as native JavaScript string or bytes this.date = new Date(); diff --git a/src/packet/marker.js b/src/packet/marker.js index 2de62367..d9f2f35e 100644 --- a/src/packet/marker.js +++ b/src/packet/marker.js @@ -15,18 +15,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/marker */ /** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * + * Implementation of the strange "Marker packet" (Tag 10)
      + *
      * RFC4880 5.8: An experimental version of PGP used this packet as the Literal * packet, but no released version of PGP generated Literal packets with this * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * + * the Marker packet.
      + *
      * Such a packet MUST be ignored when received. + * @module packet/marker + */ + +/** + * @constructor */ module.exports = function () { /** diff --git a/src/packet/one_pass_signature.js b/src/packet/one_pass_signature.js index 2c60ac51..12b056d5 100644 --- a/src/packet/one_pass_signature.js +++ b/src/packet/one_pass_signature.js @@ -15,24 +15,27 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/one_pass_signature */ - -var enums = require('../enums.js'), - type_keyid = require('../type/keyid.js'); - /** - * @class - * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) - * + * Implementation of the One-Pass Signature Packets (Tag 4)
      + *
      * RFC4880 5.4: * The One-Pass Signature packet precedes the signed data and contains * enough information to allow the receiver to begin calculating any * hashes needed to verify the signature. It allows the Signature * packet to be placed at the end of the message, so that the signer * can compute the entire signed message in one pass. - */ + * @requires enums + * @requires type/keyid + * @module packet/one_pass_signature +*/ -module.exports = function one_pass_signature() { +var enums = require('../enums.js'), + type_keyid = require('../type/keyid.js'); + +/** + * @constructor + */ +module.exports = function () { this.version = null; // A one-octet version number. The current version is 3. this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) diff --git a/src/packet/packet.js b/src/packet/packet.js index dde56690..7486038c 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -15,7 +15,11 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/packet */ +/** + * @requires enums + * @requires util + * @module packet/packet + */ var enums = require('../enums.js'), util = require('../util'); diff --git a/src/packet/packetlist.js b/src/packet/packetlist.js index a681ef2f..9de92aa4 100644 --- a/src/packet/packetlist.js +++ b/src/packet/packetlist.js @@ -1,16 +1,21 @@ -/** @module packet/packetlist */ +/** + * This class represents a list of openpgp packets. + * Take care when iterating over it - the packets themselves + * are stored as numerical indices. + * @requires enums + * @requires packet + * @requires packet/packet + * @module packet/packetlist + */ var packetParser = require('./packet.js'), packets = require('./all_packets.js'), enums = require('../enums.js'); /** - * @class - * @classdesc This class represents a list of openpgp packets. - * Take care when iterating over it - the packets themselves - * are stored as numerical indices. + * @constructor */ -module.exports = function packetlist() { +module.exports = packetlist = function () { /** The number of packets contained within the list. * @readonly * @type {Integer} */ @@ -18,7 +23,7 @@ module.exports = function packetlist() { /** * Reads a stream of binary data and interprents it as a list of packets. - * @param {openpgp_byte_array} An array of bytes. + * @param {String} A binary string of bytes. */ this.read = function(bytes) { var i = 0; @@ -39,7 +44,7 @@ module.exports = function packetlist() { /** * Creates a binary representation of openpgp objects contained within the * class instance. - * @returns {openpgp_byte_array} An array of bytes containing valid openpgp packets. + * @returns {String} A binary string of bytes containing valid openpgp packets. */ this.write = function() { var bytes = ''; diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 0eb05a1f..7f6f9c95 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -15,7 +15,20 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)
      + *
      + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key + */ var util = require('../util'), type_mpi = require('../type/mpi.js'), @@ -24,15 +37,9 @@ var util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. + * @constructor */ -module.exports = function packet_public_key() { +module.exports = function () { this.version = 4; /** Key creation date. * @type {Date} */ @@ -41,7 +48,7 @@ module.exports = function packet_public_key() { * @type {module:type/mpi} */ this.mpi = []; /** Public key algorithm - * @type {openpgp.publickey} */ + * @type {module:enums.publicKey} */ this.algorithm = 'rsa_sign'; // time in days (V3 only) this.expirationTimeV3 = 0; @@ -52,11 +59,9 @@ module.exports = function packet_public_key() { * 5.5.2 Public-Key Packet Formats * called by read_tag<num> * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input * @return {Object} This object with attributes set by the parser */ - this.readPublicKey = this.read = function(bytes) { + this.read = function(bytes) { var pos = 0; // A one-octet version number (3 or 4). this.version = bytes.charCodeAt(pos++); @@ -97,19 +102,22 @@ module.exports = function packet_public_key() { } else { throw new Error('Version ' + version + ' of the key packet is unsupported.'); } - } + }; - /* + /** + * Alias of read() + * @function module:packet/public_key#readPublicKey + * @see module:packet/public_key#read + */ + this.readPublicKey = this.read; + + /** * Same as write_private_key, but has less information because of * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, + * @return {Object} {body: [string]OpenPGP packet body contents, * header: [string] OpenPGP packet header, string: [string] header+body} */ - this.writePublicKey = this.write = function() { + this.write = function() { // Version var result = String.fromCharCode(this.version); result += util.writeDate(this.created); @@ -125,16 +133,25 @@ module.exports = function packet_public_key() { } return result; - } + }; - // Write an old version packet - it's used by some of the internal routines. + /** + * Alias of write() + * @function module:packet/public_key#writePublicKey + * @see module:packet/public_key#write + */ + this.writePublicKey = this.write; + + /** + * Write an old version packet - it's used by some of the internal routines. + */ this.writeOld = function() { var bytes = this.writePublicKey(); return String.fromCharCode(0x99) + util.writeNumber(bytes.length, 2) + bytes; - } + }; /** * Calculates the key id of the key @@ -148,7 +165,7 @@ module.exports = function packet_public_key() { keyid.read(this.mpi[0].write().substr(-8)); } return keyid; - } + }; /** * Calculates the fingerprint of the key @@ -166,6 +183,5 @@ module.exports = function packet_public_key() { } return crypto.hash.md5(toHash) } - } - -} + }; +}; diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js index c52ec97d..9d14a8f3 100644 --- a/src/packet/public_key_encrypted_session_key.js +++ b/src/packet/public_key_encrypted_session_key.js @@ -15,19 +15,9 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_key_encrypted_session_key */ - -var type_keyid = require('../type/keyid.js'), - util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)
      + *
      * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -39,8 +29,24 @@ var type_keyid = require('../type/keyid.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/public_key_encrypted_session_key */ -module.exports = function packet_public_key_encrypted_session_key() { + +var type_keyid = require('../type/keyid.js'), + util = require('../util'), + type_mpi = require('../type/mpi.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.version = 3; this.publicKeyId = new type_keyid(); @@ -90,7 +96,7 @@ module.exports = function packet_public_key_encrypted_session_key() { i += mpi.read(bytes.substr(i)); this.encrypted.push(mpi); } - } + }; /** * Create a string representation of a tag 1 packet @@ -122,7 +128,7 @@ module.exports = function packet_public_key_encrypted_session_key() { } return result; - } + }; this.encrypt = function(key) { var data = String.fromCharCode( @@ -141,7 +147,7 @@ module.exports = function packet_public_key_encrypted_session_key() { this.publicKeyAlgorithm, key.mpi, mpi); - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -172,5 +178,5 @@ module.exports = function packet_public_key_encrypted_session_key() { this.sessionKeyAlgorithm = enums.read(enums.symmetric, decoded.charCodeAt(0)); } - } + }; }; diff --git a/src/packet/public_subkey.js b/src/packet/public_subkey.js index 19c3513f..0b94870f 100644 --- a/src/packet/public_subkey.js +++ b/src/packet/public_subkey.js @@ -15,10 +15,17 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/public_subkey */ +/** + * @requires packet/public_key + * @module packet/public_subkey + */ -var public_key = require('./public_key.js'); +var publicKey = require('./public_key.js'); -module.exports = function public_subkey() { - public_key.call(this); +/** + * @constructor + * @extends module:packet/public_key + */ +module.exports = function () { + publicKey.call(this); } diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index 4a41084f..03dcd12e 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -15,7 +15,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_key */ +/** + * Implementation of the Key Material Packet (Tag 5,6,7,14)
      + *
      + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + * @requires crypto + * @requires enums + * @requires packet/public_key + * @requires type/mpi + * @requires type/s2k + * @requires util + * @module packet/secret_key + */ var publicKey = require('./public_key.js'), enums = require('../enums.js'), @@ -25,14 +39,8 @@ var publicKey = require('./public_key.js'), type_s2k = require('../type/s2k.js'); /** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) + * @constructor * @extends module:packet/public_key - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. */ module.exports = function () { publicKey.call(this); @@ -185,9 +193,8 @@ module.exports = function () { /** * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed + * @link module:packet/secret_key.isDecrypted should be + * false otherwise a call to this function is not needed * * @param {String} str_passphrase The passphrase for this private key * as string diff --git a/src/packet/secret_subkey.js b/src/packet/secret_subkey.js index d1eec8e3..97a69fee 100644 --- a/src/packet/secret_subkey.js +++ b/src/packet/secret_subkey.js @@ -15,10 +15,17 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/secret_subkey */ +/** + * @requires packet/secret_key + * @module packet/secret_subkey + */ -var secret_key = require('./secret_key.js'); +var secretKey = require('./secret_key.js'); -module.exports = function secret_subkey() { - secret_key.call(this); +/** + * @constructor + * @extends module:packet/secret_key + */ +module.exports = function () { + secretKey.call(this); } diff --git a/src/packet/signature.js b/src/packet/signature.js index 3d6aaa63..fa2d3f8a 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -15,7 +15,21 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/signature */ +/** + * Implementation of the Signature Packet (Tag 2)
      + *
      + * RFC4480 5.2: + * A Signature packet describes a binding between some public key and + * some data. The most common signatures are a signature of a file or a + * block of text, and a signature that is a certification of a User ID. + * @requires crypto + * @requires enums + * @requires packet/packet + * @requires type/keyid + * @requires type/mpi + * @requires util + * @module packet/signature + */ var util = require('../util'), packet = require('./packet.js'), @@ -25,15 +39,9 @@ var util = require('../util'), type_keyid = require('../type/keyid.js'); /** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. + * @constructor */ -module.exports = function packet_signature() { +module.exports = packetSignature = function () { this.version = 4; this.signatureType = null; @@ -94,7 +102,7 @@ module.exports = function packet_signature() { case 3: // One-octet length of following hashed material. MUST be 5. if (bytes.charCodeAt(i++) != 5) - util.print_debug("openpgp.packet.signature.js\n" + + util.print_debug("packet/signature.js\n" + 'invalid One-octet length of following hashed material.' + 'MUST be 5. @:' + (i - 1)); @@ -491,7 +499,7 @@ module.exports = function packet_signature() { break; case 32: // Embedded Signature - this.embeddedSignature = new packet_signature(); + this.embeddedSignature = new packetSignature(); this.embeddedSignature.read(bytes.substr(mypos)); break; default: diff --git a/src/packet/sym_encrypted_integrity_protected.js b/src/packet/sym_encrypted_integrity_protected.js index 636222df..5a2998bb 100644 --- a/src/packet/sym_encrypted_integrity_protected.js +++ b/src/packet/sym_encrypted_integrity_protected.js @@ -15,24 +15,27 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_integrity_protected */ - -var util = require('../util'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * + * Implementation of the Sym. Encrypted Integrity Protected Data + * Packet (Tag 18)
      + *
      * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is * a variant of the Symmetrically Encrypted Data packet. It is a new feature * created for OpenPGP that addresses the problem of detecting a modification to * encrypted data. It is used in combination with a Modification Detection Code * packet. + * @requires crypto + * @requires util + * @module packet/sym_encrypted_integrity_protected */ -module.exports = function packet_sym_encrypted_integrity_protected() { +var util = require('../util'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { /** The encrypted payload. */ this.encrypted = null; // string /** @@ -42,12 +45,11 @@ module.exports = function packet_sym_encrypted_integrity_protected() { * @type {Boolean} */ this.modification = false; - this.packets; + this.packets = null; this.read = function(bytes) { - // - A one-octet version number. The only currently defined value is - // 1. + // - A one-octet version number. The only currently defined value is 1. var version = bytes.charCodeAt(0); if (version != 1) { @@ -58,13 +60,13 @@ module.exports = function packet_sym_encrypted_integrity_protected() { // operating in Cipher Feedback mode with shift amount equal to the // block size of the cipher (CFB-n where n is the block size). this.encrypted = bytes.substr(1); - } + }; this.write = function() { return String.fromCharCode(1) // Version + this.encrypted; - } + }; this.encrypt = function(sessionKeyAlgorithm, key) { var bytes = this.packets.write() @@ -87,7 +89,7 @@ module.exports = function packet_sym_encrypted_integrity_protected() { this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false).substring(0, prefix.length + tohash.length); - } + }; /** * Decrypts the encrypted data contained in this object read_packet must @@ -115,5 +117,5 @@ module.exports = function packet_sym_encrypted_integrity_protected() { throw new Error('Modification detected.'); } else this.packets.read(decrypted.substr(0, decrypted.length - 22)); - } + }; }; diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js index 9cc80a57..0fb88ff3 100644 --- a/src/packet/sym_encrypted_session_key.js +++ b/src/packet/sym_encrypted_session_key.js @@ -15,16 +15,9 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/sym_encrypted_session_key */ - -var type_s2k = require('../type/s2k.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - /** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * + * Public-Key Encrypted Session Key Packets (Tag 1)
      + *
      * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key * used to encrypt a message. Zero or more Public-Key Encrypted Session Key * packets and/or Symmetric-Key Encrypted Session Key packets may precede a @@ -36,8 +29,20 @@ var type_s2k = require('../type/s2k.js'), * The recipient of the message finds a session key that is encrypted to their * public key, decrypts the session key, and then uses the session key to * decrypt the message. + * @requires crypto + * @requires enums + * @requires type/s2k + * @module packet/sym_encrypted_session_key */ -module.exports = function packet_sym_encrypted_session_key() { + +var type_s2k = require('../type/s2k.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 3; this.sessionKeyEncryptionAlgorithm = null; this.sessionKeyAlgorithm = 'aes256'; @@ -73,7 +78,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKeyEncryptionAlgorithm = algo } else this.sessionKeyAlgorithm = algo; - } + }; this.write = function() { var algo = this.encrypted == null ? @@ -87,7 +92,7 @@ module.exports = function packet_sym_encrypted_session_key() { if (this.encrypted != null) bytes += this.encrypted; return bytes; - } + }; /** * Decrypts the session key (only for public key encrypted session key @@ -116,7 +121,7 @@ module.exports = function packet_sym_encrypted_session_key() { this.sessionKey = decrypted.substr(1); } - } + }; this.encrypt = function(passphrase) { var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); @@ -131,5 +136,5 @@ module.exports = function packet_sym_encrypted_session_key() { this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), this.sessionKeyEncryptionAlgorithm, key, private_key, true); - } + }; }; diff --git a/src/packet/symmetrically_encrypted.js b/src/packet/symmetrically_encrypted.js index 2e1c69d2..8f50b76a 100644 --- a/src/packet/symmetrically_encrypted.js +++ b/src/packet/symmetrically_encrypted.js @@ -15,34 +15,36 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/symmetrically_encrypted */ - -var crypto = require('../crypto'); - /** - * @class - * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) - * + * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
      + *
      * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted * with a symmetric-key algorithm. When it has been decrypted, it contains other * packets (usually a literal data packet or compressed data packet, but in * theory other Symmetrically Encrypted Data packets or sequences of packets * that form whole OpenPGP messages). + * @requires crypto + * @module packet/symmetrically_encrypted */ -module.exports = function packet_symmetrically_encrypted() { +var crypto = require('../crypto'); + +/** + * @constructor + */ +module.exports = function () { this.encrypted = null; /** Decrypted packets contained within. * @type {module:packet/packetlist} */ - this.packets; + this.packets = null; this.read = function(bytes) { this.encrypted = bytes; - } + }; this.write = function() { return this.encrypted; - } + }; /** * Symmetrically decrypt the packet data @@ -52,19 +54,18 @@ module.exports = function packet_symmetrically_encrypted() { * @param {String} key * Key as string with the corresponding length to the * algorithm - * @return The decrypted data; */ this.decrypt = function(sessionKeyAlgorithm, key) { var decrypted = crypto.cfb.decrypt( sessionKeyAlgorithm, key, this.encrypted, true); this.packets.read(decrypted); - } + }; this.encrypt = function(algo, key) { var data = this.packets.write(); this.encrypted = crypto.cfb.encrypt( crypto.getPrefixRandom(algo), algo, data, key, true); - } + }; }; diff --git a/src/packet/trust.js b/src/packet/trust.js index 6d4c374d..d3a3ec9a 100644 --- a/src/packet/trust.js +++ b/src/packet/trust.js @@ -1,3 +1,10 @@ -module.exports = function packet_trust() { +/** + * @module packet/trust + */ + +/** + * @constructor + */ +module.exports = function () { }; diff --git a/src/packet/user_attribute.js b/src/packet/user_attribute.js index a8e0277b..2f8b8631 100644 --- a/src/packet/user_attribute.js +++ b/src/packet/user_attribute.js @@ -15,44 +15,48 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/user_attribute */ - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. +/** + * Implementation of the User Attribute Packet (Tag 17)
      + *
      + * The User Attribute packet is a variation of the User ID packet. It + * is capable of storing more types of data than the User ID packet, + * which is limited to text. Like the User ID packet, a User Attribute + * packet may be certified by the key owner ("self-signed") or any other + * key owner who cares to certify it. Except as noted, a User Attribute + * packet may be used anywhere that a User ID packet may be used. + *
      + * While User Attribute packets are not a required part of the OpenPGP + * standard, implementations SHOULD provide at least enough + * compatibility to properly handle a certification signature on the + * User Attribute packet. A simple way to do this is by treating the + * User Attribute packet as a User ID packet with opaque contents, but + * an implementation may use any method desired. + * module packet/user_attribute + * @module packet/user_attribute */ -module.exports = function packet_user_attribute() { + +var util = require('../util'), + packet = require('./packet.js'); + +/** + * @constructor + */ +module.exports = function () { this.tag = 17; this.attributes = []; /** * parsing function for a user attribute packet (tag 17). * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {module:packet/user_attribute} object representation */ this.read = function(bytes) { var i = 0; while (i < bytes.length) { - var len = openpgp_packet.read_simple_length(bytes); - + var len = packet.readSimpleLength(bytes.substr(i)); i += len.offset; + this.attributes.push(bytes.substr(i, len.len)); i += len.len; } - } + }; }; diff --git a/src/packet/userid.js b/src/packet/userid.js index 256ea28f..74df385e 100644 --- a/src/packet/userid.js +++ b/src/packet/userid.js @@ -15,20 +15,24 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module packet/userid */ - -var util = require('../util'); - /** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) + * Implementation of the User ID Packet (Tag 13)
      + *
      * A User ID packet consists of UTF-8 text that is intended to represent * the name and email address of the key holder. By convention, it * includes an RFC 2822 [RFC2822] mail name-addr, but there are no * restrictions on its content. The packet length in the header - * specifies the length of the User ID. + * specifies the length of the User ID. + * @requires util + * @module packet/userid */ -module.exports = function packet_userid() { + +var util = require('../util'); + +/** + * @constructor + */ +module.exports = function () { /** A string containing the user id. Usually in the form * John Doe * @type {String} @@ -39,21 +43,16 @@ module.exports = function packet_userid() { /** * Parsing function for a user id packet (tag 13). * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input - * at position - * @return {module:packet/userid} object representation */ - this.read = function(bytes) { + this.read = function (bytes) { this.userid = util.decode_utf8(bytes); - } + }; /** * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe + *
      + * A Key ID is an eight-octet scalar that identifies a key. + * Implementations SHOULD NOT assume that Key IDs are unique. The + * section "Enhanced Key Formats" below describes how Key IDs are + * formed. + * @requires util + * @module type/keyid + */ var util = require('../util'); /** - * @class - * @classdesc Implementation of type key id (RFC4880 3.3) - * A Key ID is an eight-octet scalar that identifies a key. - Implementations SHOULD NOT assume that Key IDs are unique. The - section "Enhanced Key Formats" below describes how Key IDs are - formed. + * @constructor */ -module.exports = function keyid() { +module.exports = function () { this.bytes = ''; @@ -35,30 +39,27 @@ module.exports = function keyid() { /** * Parsing method for a key id * @param {String} input Input to read the key id from - * @param {integer} position Position where to start reading the key - * id from input - * @return {module:type/keyid} This object */ this.read = function(bytes) { this.bytes = bytes.substr(0, 8); - } + }; this.write = function() { return this.bytes; - } + }; this.toHex = function() { return util.hexstrdump(this.bytes); - } + }; this.equals = function(keyid) { return this.bytes == keyid.bytes; - } + }; this.isNull = function() { return this.bytes === ''; - } -} + }; +}; module.exports.mapToHex = function(keyId) { return keyId.toHex(); diff --git a/src/type/mpi.js b/src/type/mpi.js index 37c19733..03834823 100644 --- a/src/type/mpi.js +++ b/src/type/mpi.js @@ -20,20 +20,25 @@ // - MPI size: (a << 8) | b // - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) -/** @module type/mpi */ - -var BigInteger = require('../crypto/public_key/jsbn.js'), - util = require('../util'); - /** - * @class - * @classdescImplementation of type MPI (RFC4880 3.2) + * Implementation of type MPI (RFC4880 3.2)
      + *
      * Multiprecision integers (also called MPIs) are unsigned integers used * to hold large integers such as the ones used in cryptographic * calculations. * An MPI consists of two pieces: a two-octet scalar that is the length * of the MPI in bits followed by a string of octets that contain the * actual integer. + * @requires crypto/public_key/jsbn + * @requires util + * @module type/mpi + */ + +var BigInteger = require('../crypto/public_key/jsbn.js'), + util = require('../util'); + +/** + * @constructor */ module.exports = function mpi() { /** An implementation dependent integer */ @@ -42,11 +47,7 @@ module.exports = function mpi() { /** * Parsing function for a mpi (RFC 4880 3.2). * @param {String} input Payload of mpi data - * @param {Integer} position Position to start reading from the input - * string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {module:type/mpi} Object representation + * @return {Integer} Length of data read */ this.read = function(bytes) { var bits = (bytes.charCodeAt(0) << 8) | bytes.charCodeAt(1); @@ -67,19 +68,19 @@ module.exports = function mpi() { this.fromBytes(raw); return 2 + bytelen; - } + }; this.fromBytes = function(bytes) { this.data = new BigInteger(util.hexstrdump(bytes), 16); - } + }; this.toBytes = function() { return this.write().substr(2); - } + }; this.byteLength = function() { return this.toBytes().length; - } + }; /** * Converts the mpi object to a string as specified in RFC4880 3.2 @@ -87,13 +88,13 @@ module.exports = function mpi() { */ this.write = function() { return this.data.toMPI(); - } + }; this.toBigInteger = function() { return this.data.clone(); - } + }; this.fromBigInteger = function(bn) { this.data = bn.clone(); - } + }; } diff --git a/src/type/s2k.js b/src/type/s2k.js index 58c3c5df..f29f5849 100644 --- a/src/type/s2k.js +++ b/src/type/s2k.js @@ -15,39 +15,45 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module type/s2k */ +/** + * Implementation of the String-to-key specifier (RFC4880 3.7)
      + *
      + * String-to-key (S2K) specifiers are used to convert passphrase strings + * into symmetric-key encryption/decryption keys. They are used in two + * places, currently: to encrypt the secret part of private keys in the + * private keyring, and to convert passphrases to encryption keys for + * symmetrically encrypted messages. + * @requires crypto + * @requires enums + * @requires util + * @module type/s2k + */ var enums = require('../enums.js'), util = require('../util'), crypto = require('../crypto'); /** - * @class - * @classdesc Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. + * @constructor */ module.exports = function s2k() { - /** @type {openpgp.hash} */ + /** @type {module:enums.hash} */ this.algorithm = 'sha256'; - /** @type {module:type/s2k} */ + /** @type {module:enums.s2k} */ this.type = 'iterated'; this.c = 96; - /** Eight bytes of salt. - * @type {openpgp_byte_array} + /** Eight bytes of salt in a binary string. + * @type {String} */ this.salt = crypto.random.getRandomBytes(8); - // Exponen bias, defined in RFC4880 + // Exponent bias, defined in RFC4880 var expbias = 6; this.get_count = function() { return (16 + (this.c & 15)) << ((this.c >> 4) + expbias); - } + }; /** * Parsing function for a string-to-key specifier (RFC 4880 3.7). @@ -97,7 +103,7 @@ module.exports = function s2k() { } return i; - } + }; /** @@ -118,10 +124,10 @@ module.exports = function s2k() { bytes += this.salt; bytes += String.fromCharCode(this.c); break; - }; + } return bytes; - } + }; /** * Produces a key using the specified passphrase and the defined @@ -158,7 +164,7 @@ module.exports = function s2k() { isp = isp.substr(0, count); return crypto.hash.digest(algorithm, prefix + isp); - }; + } } var result = '', @@ -170,5 +176,5 @@ module.exports = function s2k() { } return result.substr(0, numBytes); - } -} + }; +}; diff --git a/src/util/util.js b/src/util/util.js index 448fbcfc..83450a96 100644 --- a/src/util/util.js +++ b/src/util/util.js @@ -15,20 +15,16 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** @module util/util */ +/** + * This object contains utility functions + * @requires config + * @module util/util + */ var config = require('../config'); -/** - * - * This object contains utility functions - * - * @class - * @classdesc Implementation of the util object - */ -var Util = function() { - - this.readNumber = function(bytes) { +module.exports = { + readNumber: function (bytes) { var n = 0; for (var i = 0; i < bytes.length; i++) { @@ -37,37 +33,33 @@ var Util = function() { } return n; - }; + }, - this.writeNumber = function(n, bytes) { + writeNumber: function (n, bytes) { var b = ''; for (var i = 0; i < bytes; i++) { b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); } return b; - }; + }, - - - this.readDate = function(bytes) { + readDate: function (bytes) { var n = this.readNumber(bytes); var d = new Date(); d.setTime(n * 1000); return d; - }; + }, - this.writeDate = function(time) { + writeDate: function (time) { var numeric = Math.round(time.getTime() / 1000); return this.writeNumber(numeric, 4); - }; + }, - this.emailRegEx = /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/; + emailRegEx: /^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/, - this.debug = false; - - this.hexdump = function(str) { + hexdump: function (str) { var r = []; var e = str.length; var c = 0; @@ -82,14 +74,14 @@ var Util = function() { r.push("\n "); } return r.join(''); - }; + }, /** * Create hexstring from a binary * @param {String} str String to convert * @return {String} String containing the hexadecimal values */ - this.hexstrdump = function(str) { + hexstrdump: function (str) { if (str == null) return ""; var r = []; @@ -102,26 +94,26 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** * Create binary string from a hex encoded string * @param {String} str Hex string to convert * @return {String} String containing the binary values */ - this.hex2bin = function(hex) { + hex2bin: function (hex) { var str = ''; for (var i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); return str; - }; + }, /** * Creating a hex string from an binary array of integers (0..255) * @param {String} str Array of bytes to convert * @return {String} Hexadecimal representation of the array */ - this.hexidump = function(str) { + hexidump: function (str) { var r = []; var e = str.length; var c = 0; @@ -132,7 +124,7 @@ var Util = function() { r.push("" + h); } return r.join(''); - }; + }, /** @@ -140,32 +132,29 @@ var Util = function() { * @param {String} str The string to convert * @return {String} A valid squence of utf8 bytes */ - this.encode_utf8 = function(str) { + encode_utf8: function (str) { return unescape(encodeURIComponent(str)); - }; + }, /** * Convert a string of utf8 bytes to a native javascript string * @param {String} utf8 A valid squence of utf8 bytes * @return {String} A native javascript string */ - this.decode_utf8 = function(utf8) { + decode_utf8: function (utf8) { try { return decodeURIComponent(escape(utf8)); } catch (e) { return utf8; } - }; + }, - var str2bin = function(str, result) { - for (var i = 0; i < str.length; i++) { - result[i] = str.charCodeAt(i); - } - - return result; - }; - - var bin2str = function(bin) { + /** + * Convert an array of integers(0.255) to a string + * @param {Array} bin An array of (binary) integers to convert + * @return {String} The string representation of the array + */ + bin2str: function (bin) { var result = []; for (var i = 0; i < bin.length; i++) { @@ -173,53 +162,57 @@ var Util = function() { } return result.join(''); - }; + }, + + _str2bin: function (str, result) { + for (var i = 0; i < str.length; i++) { + result[i] = str.charCodeAt(i); + } + + return result; + }, /** * Convert a string to an array of integers(0.255) * @param {String} str String to convert * @return {Array} An array of (binary) integers */ - this.str2bin = function(str) { - return str2bin(str, new Array(str.length)); - }; + str2bin: function (str) { + return this._str2bin(str, new Array(str.length)); + }, - /** - * Convert an array of integers(0.255) to a string - * @param {Array} bin An array of (binary) integers to convert - * @return {String} The string representation of the array - */ - this.bin2str = bin2str; - /** * Convert a string to a Uint8Array * @param {String} str String to convert * @return {Uint8Array} The array of (binary) integers */ - this.str2Uint8Array = function(str) { - return str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); - }; + str2Uint8Array: function (str) { + return this._str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); + }, /** * Convert a Uint8Array to a string. This currently functions - * the same as bin2str. + * the same as bin2str. + * @function module:util/util.Uint8Array2str * @param {Uint8Array} bin An array of (binary) integers to convert * @return {String} String representation of the array */ - this.Uint8Array2str = bin2str; + Uint8Array2str: function (bin) { + return this.bin2str(bin); + }, /** - * Calculates a 16bit sum of a string by adding each character + * Calculates a 16bit sum of a string by adding each character * codes modulus 65535 * @param {String} text String to create a sum of - * @return {Integer} An integer containing the sum of all character + * @return {Integer} An integer containing the sum of all character * codes % 65535 */ - this.calc_checksum = function(text) { + calc_checksum: function (text) { var checksum = { s: 0, - add: function(sadd) { + add: function (sadd) { this.s = (this.s + sadd) % 65536; } }; @@ -227,42 +220,42 @@ var Util = function() { checksum.add(text.charCodeAt(i)); } return checksum.s; - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * @param {String} str String of the debug message */ - this.print_debug = function(str) { + print_debug: function (str) { if (config.debug) { console.log(str); } - }; + }, /** * Helper function to print a debug message. Debug * messages are only printed if - * openpgp.config.debug is set to true. + * @link module:config/config.debug is set to true. * Different than print_debug because will call hexstrdump iff necessary. * @param {String} str String of the debug message */ - this.print_debug_hexstr_dump = function(str, strToHex) { + print_debug_hexstr_dump: function (str, strToHex) { if (config.debug) { str = str + this.hexstrdump(strToHex); console.log(str); } - }; + }, - this.getLeftNBits = function(string, bitcount) { + getLeftNBits: function (string, bitcount) { var rest = bitcount % 8; if (rest == 0) return string.substring(0, bitcount / 8); var bytes = (bitcount - rest) / 8 + 1; var result = string.substring(0, bytes); return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; + }, /** * Shifting a string to n bits right @@ -271,7 +264,7 @@ var Util = function() { * than 9) * @return {String} Resulting string. */ - this.shiftRight = function(value, bitcount) { + shiftRight: function (value, bitcount) { var temp = util.str2bin(value); if (bitcount % 8 != 0) { for (var i = temp.length - 1; i >= 0; i--) { @@ -283,13 +276,13 @@ var Util = function() { return value; } return util.bin2str(temp); - }; + }, /** * Return the algorithm type as string * @return {String} String representing the message type */ - this.get_hashAlgorithmString = function(algo) { + get_hashAlgorithmString: function (algo) { switch (algo) { case 1: return "MD5"; @@ -307,12 +300,5 @@ var Util = function() { return "SHA224"; } return "unknown"; - }; - + } }; - -/** - * an instance that should be used. - */ - -module.exports = new Util(); diff --git a/test/ci-quick.js b/test/ci-quick.js index ec733911..bcc64ffe 100644 --- a/test/ci-quick.js +++ b/test/ci-quick.js @@ -66,7 +66,7 @@ describe('Openpgp integration tests', function() { describe('Import key pair', function() { it('should work', function(done) { // clear any keypair already in the keychain - keyring.init(); + keyring.clear(); keyring.importKey(privkey); keyring.importKey(pubkey); done(); diff --git a/test/general/keyring.js b/test/general/keyring.js index 00c75b7e..a328f160 100644 --- a/test/general/keyring.js +++ b/test/general/keyring.js @@ -6,7 +6,6 @@ unit.register("Keyring testing", function() { var keyring = new keyringClass(); var result = []; - keyring.init(); keyring.importKey([ '-----BEGIN PGP PUBLIC KEY BLOCK-----', 'Version: GnuPG v1.4.11 (GNU/Linux)',