snarkjs-algorand 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,601 @@
1
+ // contracts/clients/PlonkVerifier.ts
2
+ import "@algorandfoundation/algokit-utils/types/algorand-client";
3
+ import "@algorandfoundation/algokit-utils/types/app";
4
+ import { getArc56ReturnValue, getABIStructFromABITuple } from "@algorandfoundation/algokit-utils/types/app-arc56";
5
+ import {
6
+ AppClient as _AppClient
7
+ } from "@algorandfoundation/algokit-utils/types/app-client";
8
+ import { AppFactory as _AppFactory } from "@algorandfoundation/algokit-utils/types/app-factory";
9
+ import "@algorandfoundation/algokit-utils/types/composer";
10
+ import "@algorandfoundation/algokit-utils/types/transaction";
11
+ import "algosdk";
12
+ var APP_SPEC = { "name": "PlonkVerifier", "structs": { "Proof": [{ "name": "a", "type": "byte[96]" }, { "name": "b", "type": "byte[96]" }, { "name": "c", "type": "byte[96]" }, { "name": "z", "type": "byte[96]" }, { "name": "t1", "type": "byte[96]" }, { "name": "t2", "type": "byte[96]" }, { "name": "t3", "type": "byte[96]" }, { "name": "wxi", "type": "byte[96]" }, { "name": "wxiw", "type": "byte[96]" }, { "name": "evalA", "type": "uint256" }, { "name": "evalB", "type": "uint256" }, { "name": "evalC", "type": "uint256" }, { "name": "evalS1", "type": "uint256" }, { "name": "evalS2", "type": "uint256" }, { "name": "evalZw", "type": "uint256" }], "VerificationKey": [{ "name": "qm", "type": "byte[96]" }, { "name": "ql", "type": "byte[96]" }, { "name": "qr", "type": "byte[96]" }, { "name": "qo", "type": "byte[96]" }, { "name": "qc", "type": "byte[96]" }, { "name": "s1", "type": "byte[96]" }, { "name": "s2", "type": "byte[96]" }, { "name": "s3", "type": "byte[96]" }, { "name": "power", "type": "uint64" }, { "name": "nPublic", "type": "uint64" }, { "name": "k1", "type": "uint64" }, { "name": "k2", "type": "uint64" }, { "name": "x_2", "type": "byte[192]" }] }, "methods": [{ "name": "_dummy", "args": [{ "type": "(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192])", "struct": "VerificationKey", "name": "_vk" }], "returns": { "type": "void" }, "actions": { "create": [], "call": ["CloseOut"] }, "readonly": false, "desc": "Dummy function that only exists so we can have the VerificationKey type in the generated client", "events": [], "recommendations": {} }, { "name": "verify", "args": [{ "type": "uint256[]", "name": "signals" }, { "type": "(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256)", "struct": "Proof", "name": "proof" }], "returns": { "type": "void" }, "actions": { "create": [], "call": ["NoOp"] }, "readonly": false, "events": [], "recommendations": {} }], "arcs": [22, 28], "networks": {}, "state": { "schema": { "global": { "ints": 0, "bytes": 0 }, "local": { "ints": 0, "bytes": 0 } }, "keys": { "global": {}, "local": {}, "box": {} }, "maps": { "global": {}, "local": {}, "box": {} } }, "bareActions": { "create": ["NoOp"], "call": [] }, "sourceInfo": { "approval": { "sourceInfo": [{ "pc": [1293], "errorMessage": "Fr inverse of zero" }, { "pc": [440], "errorMessage": "Length must be 192" }, { "pc": [104], "errorMessage": "Length must be 32" }, { "pc": [179, 202, 225, 248, 271, 294, 317, 340, 1849, 1858, 1989, 1999, 2026, 2035, 2042, 2109, 2119, 2345, 2364, 2374, 2403, 2412, 2423, 2430, 2458], "errorMessage": "Length must be 96" }, { "pc": [50], "errorMessage": "OnCompletion is not CloseOut" }, { "pc": [30], "errorMessage": "OnCompletion is not NoOp" }, { "pc": [2516], "errorMessage": "Verification failed" }, { "pc": [64], "errorMessage": "can only call when creating" }, { "pc": [33, 53], "errorMessage": "can only call when not creating" }, { "pc": [574, 758, 787, 790, 809, 1030, 1044, 1058, 1072, 1085, 1513, 1528, 2063, 2068, 2075, 2084, 2093], "errorMessage": "index access is out of bounds" }, { "pc": [1410], "errorMessage": "max array length exceeded" }, { "pc": [94, 133, 800, 1145, 1170, 1401, 1549, 1724], "errorMessage": "overflow" }], "pcOffsetMethod": "cblocks" }, "clear": { "sourceInfo": [], "pcOffsetMethod": "none" } }, "source": { "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgOTYgMzIgMSAwIDM4NCAxOTIgMjg4IDQ4MCA1NzYgNjcyIDc2OCA3NzYgNzg0IDc5MiA4MDAgOTkyIDM1MiBUTVBMX0RFQlVHX0xPR0dJTkcKICAgIGJ5dGVjYmxvY2sgMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxIFRNUExfVkVSSUZJQ0FUSU9OX0tFWSAweCAweDAxIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMCBUTVBMX1JPT1RfT0ZfVU5JVFkgMHgwMjRhYTJiMmYwOGYwYTkxMjYwODA1MjcyZGM1MTA1MWM2ZTQ3YWQ0ZmE0MDNiMDJiNDUxMGI2NDdhZTNkMTc3MGJhYzAzMjZhODA1YmJlZmQ0ODA1NmM4YzEyMWJkYjgxM2UwMmI2MDUyNzE5ZjYwN2RhY2QzYTA4ODI3NGY2NTU5NmJkMGQwOTkyMGI2MWFiNWRhNjFiYmRjN2Y1MDQ5MzM0Y2YxMTIxMzk0NWQ1N2U1YWM3ZDA1NWQwNDJiN2UwY2U1ZDUyNzcyN2Q2ZTExOGNjOWNkYzZkYTJlMzUxYWFkZmQ5YmFhOGNiZGQzYTc2ZDQyOWE2OTUxNjBkMTJjOTIzYWM5Y2MzYmFjYTI4OWUxOTM1NDg2MDhiODI4MDEwNjA2YzRhMDJlYTczNGNjMzJhY2QyYjAyYmMyOGI5OWNiM2UyODdlODVhNzYzYWYyNjc0OTJhYjU3MmU5OWFiM2YzNzBkMjc1Y2VjMWRhMWFhYTkwNzVmZjA1Zjc5YmUKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjEwCiAgICAvLyBleHBvcnQgY2xhc3MgUGxvbmtWZXJpZmllciBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBtYWluX2JhcmVfcm91dGluZ0A3CiAgICBwdXNoYnl0ZXNzIDB4OTVjMTBjZTQgMHg0M2Q5MGEzOCAvLyBtZXRob2QgIl9kdW1teSgoYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LGJ5dGVbMTkyXSkpdm9pZCIsIG1ldGhvZCAidmVyaWZ5KHVpbnQyNTZbXSwoYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sYnl0ZVs5Nl0sdWludDI1Nix1aW50MjU2LHVpbnQyNTYsdWludDI1Nix1aW50MjU2LHVpbnQyNTYpKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBtYWluX19kdW1teV9yb3V0ZUAzIG1haW5fdmVyaWZ5X3JvdXRlQDQKCm1haW5fYWZ0ZXJfaWZfZWxzZUAxMToKICAgIGVycgoKbWFpbl92ZXJpZnlfcm91dGVANDoKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjE1CiAgICAvLyB2ZXJpZnkoc2lnbmFsczogUHVibGljU2lnbmFscywgcHJvb2Y6IFByb29mKTogdm9pZCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjEwCiAgICAvLyBleHBvcnQgY2xhc3MgUGxvbmtWZXJpZmllciBleHRlbmRzIENvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjE1CiAgICAvLyB2ZXJpZnkoc2lnbmFsczogUHVibGljU2lnbmFscywgcHJvb2Y6IFByb29mKTogdm9pZCB7CiAgICBjYWxsc3ViIHZlcmlmeQogICAgaW50Y18yIC8vIDEKICAgIHJldHVybgoKbWFpbl9fZHVtbXlfcm91dGVAMzoKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjEyCiAgICAvLyBAYWJpbWV0aG9kKHsgYWxsb3dBY3Rpb25zOiAiQ2xvc2VPdXQiIH0pCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBwdXNoaW50IDIgLy8gQ2xvc2VPdXQKICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBDbG9zZU91dAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICBpbnRjXzIgLy8gMQogICAgcmV0dXJuCgptYWluX2JhcmVfcm91dGluZ0A3OgogICAgLy8gY29udHJhY3RzL3ZlcmlmaWVyLmFsZ28udHM6MTAKICAgIC8vIGV4cG9ydCBjbGFzcyBQbG9ua1ZlcmlmaWVyIGV4dGVuZHMgQ29udHJhY3QgewogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAxMQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMiAvLyAxCiAgICByZXR1cm4KCgovLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo6ZnJTdWIoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKZnJTdWI6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxMzMKICAgIC8vIGZ1bmN0aW9uIGZyU3ViKGE6IGJpZ3VpbnQsIGI6IGJpZ3VpbnQpOiBiaWd1aW50IHsKICAgIHByb3RvIDIgMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTM1CiAgICAvLyBjb25zdCBhTjogYmlndWludCA9IGEgJSByOwogICAgZnJhbWVfZGlnIC0yCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjEzNgogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIGZyYW1lX2RpZyAtMQogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxMzcKICAgIC8vIHJldHVybiAoYU4gKyByIC0gYk4pICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiKwogICAgc3dhcAogICAgYi0KICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgcmV0c3ViCgoKLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OmIzMihhOiBieXRlcykgLT4gYnl0ZXM6CmIzMjoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE2NQogICAgLy8gZnVuY3Rpb24gYjMyKGE6IGJpZ3VpbnQpOiBieXRlczwzMj4gewogICAgcHJvdG8gMSAxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNjYKICAgIC8vIHJldHVybiBuZXcgVWludDI1NihhKS5ieXRlcy50b0ZpeGVkKHsgbGVuZ3RoOiAzMiB9KTsKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBpbnRjXzEgLy8gMzIKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyAzMgogICAgYnplcm8KICAgIGZyYW1lX2RpZyAtMQogICAgYnwKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzEgLy8gMzIKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgMzIKICAgIHJldHN1YgoKCi8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjpkZWJ1Z0xvZyhuYW1lOiBieXRlcywgdmFsdWU6IGJ5dGVzKSAtPiB2b2lkOgpkZWJ1Z0xvZzoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIxMgogICAgLy8gZnVuY3Rpb24gZGVidWdMb2cobmFtZTogc3RyaW5nLCB2YWx1ZTogYnl0ZXMpOiB2b2lkIHsKICAgIHByb3RvIDIgMAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjEzCiAgICAvLyBpZiAoVGVtcGxhdGVWYXI8Ym9vbGVhbj4oIkRFQlVHX0xPR0dJTkciKSkgewogICAgaW50YyAxNyAvLyBUTVBMX0RFQlVHX0xPR0dJTkcKICAgIGJ6IGRlYnVnTG9nX2FmdGVyX2lmX2Vsc2VAMgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjE0CiAgICAvLyBsb2cobmFtZSk7CiAgICBmcmFtZV9kaWcgLTIKICAgIGxvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjE1CiAgICAvLyBsb2codmFsdWUpOwogICAgZnJhbWVfZGlnIC0xCiAgICBsb2cKCmRlYnVnTG9nX2FmdGVyX2lmX2Vsc2VAMjoKICAgIHJldHN1YgoKCi8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjpnZXRDaGFsbGVuZ2UodGQ6IGJ5dGVzKSAtPiBieXRlczoKZ2V0Q2hhbGxlbmdlOgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6Mzc3CiAgICAvLyBleHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbGxlbmdlKHRkOiBieXRlcyk6IFVpbnQyNTYgewogICAgcHJvdG8gMSAxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNzgKICAgIC8vIGxldCBoYXNoID0gb3Aua2VjY2FrMjU2KHRkKTsKICAgIGZyYW1lX2RpZyAtMQogICAga2VjY2FrMjU2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNTgKICAgIC8vIHJldHVybiBhICUgQkxTMTJfMzgxX1NDQUxBUl9NT0RVTFVTOwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNzkKICAgIC8vIHJldHVybiBuZXcgVWludDI1NihmclNjYWxhcihCaWdVaW50KGhhc2gpKSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18xIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gMzIKICAgIGJ6ZXJvCiAgICBifAogICAgcmV0c3ViCgoKLy8gY29udHJhY3RzL3ZlcmlmaWVyLmFsZ28udHM6OlBsb25rVmVyaWZpZXIudmVyaWZ5KHNpZ25hbHM6IGJ5dGVzLCBwcm9vZjogYnl0ZXMpIC0+IHZvaWQ6CnZlcmlmeToKICAgIC8vIGNvbnRyYWN0cy92ZXJpZmllci5hbGdvLnRzOjE1CiAgICAvLyB2ZXJpZnkoc2lnbmFsczogUHVibGljU2lnbmFscywgcHJvb2Y6IFByb29mKTogdm9pZCB7CiAgICBwcm90byAyIDAKICAgIGludGNfMyAvLyAwCiAgICBkdXBuIDMzCiAgICBieXRlY18yIC8vICIiCiAgICBkdXBuIDQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMwNAogICAgLy8gUW06IHZrQnl0ZXMuc2xpY2UoMCwgOTYpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgYnl0ZWNfMSAvLyBUTVBMX1ZFUklGSUNBVElPTl9LRVkKICAgIGxlbgogICAgaW50Y18zIC8vIDAKICAgIGRpZyAxCiAgICA+PQogICAgaW50Y18zIC8vIDAKICAgIGRpZyAyCiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgaW50Y18wIC8vIDk2CiAgICBkaWcgMgogICAgPj0KICAgIGludGNfMCAvLyA5NgogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAyCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzA1CiAgICAvLyBRbDogdmtCeXRlcy5zbGljZSg5NiwgMTkyKS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIGludGMgNSAvLyAxOTIKICAgIGRpZyAzCiAgICA+PQogICAgaW50YyA1IC8vIDE5MgogICAgZGlnIDQKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAzCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzA2CiAgICAvLyBRcjogdmtCeXRlcy5zbGljZSgxOTIsIDI4OCkudG9GaXhlZCh7IGxlbmd0aDogOTYgfSksCiAgICBpbnRjIDYgLy8gMjg4CiAgICBkaWcgNAogICAgPj0KICAgIGludGMgNiAvLyAyODgKICAgIGRpZyA1CiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZWNfMSAvLyBUTVBMX1ZFUklGSUNBVElPTl9LRVkKICAgIHVuY292ZXIgMwogICAgZGlnIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMwNwogICAgLy8gUW86IHZrQnl0ZXMuc2xpY2UoMjg4LCAzODQpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgaW50YyA0IC8vIDM4NAogICAgZGlnIDUKICAgID49CiAgICBpbnRjIDQgLy8gMzg0CiAgICBkaWcgNgogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGVjXzEgLy8gVE1QTF9WRVJJRklDQVRJT05fS0VZCiAgICB1bmNvdmVyIDMKICAgIGRpZyAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMDgKICAgIC8vIFFjOiB2a0J5dGVzLnNsaWNlKDM4NCwgNDgwKS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIGludGMgNyAvLyA0ODAKICAgIGRpZyA2CiAgICA+PQogICAgaW50YyA3IC8vIDQ4MAogICAgZGlnIDcKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAzCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzA5CiAgICAvLyBTMTogdmtCeXRlcy5zbGljZSg0ODAsIDU3NikudG9GaXhlZCh7IGxlbmd0aDogOTYgfSksCiAgICBpbnRjIDggLy8gNTc2CiAgICBkaWcgNwogICAgPj0KICAgIGludGMgOCAvLyA1NzYKICAgIGRpZyA4CiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZWNfMSAvLyBUTVBMX1ZFUklGSUNBVElPTl9LRVkKICAgIHVuY292ZXIgMwogICAgZGlnIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMxMAogICAgLy8gUzI6IHZrQnl0ZXMuc2xpY2UoNTc2LCA2NzIpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgaW50YyA5IC8vIDY3MgogICAgZGlnIDgKICAgID49CiAgICBpbnRjIDkgLy8gNjcyCiAgICBkaWcgOQogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGVjXzEgLy8gVE1QTF9WRVJJRklDQVRJT05fS0VZCiAgICB1bmNvdmVyIDMKICAgIGRpZyAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMTEKICAgIC8vIFMzOiB2a0J5dGVzLnNsaWNlKDY3MiwgNzY4KS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIGludGMgMTAgLy8gNzY4CiAgICBkaWcgOQogICAgPj0KICAgIGludGMgMTAgLy8gNzY4CiAgICBkaWcgMTAKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAzCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzEyCiAgICAvLyBwb3dlcjogb3AuYnRvaSh2a0J5dGVzLnNsaWNlKDc2OCwgNzc2KSksCiAgICBpbnRjIDExIC8vIDc3NgogICAgZGlnIDEwCiAgICA+PQogICAgaW50YyAxMSAvLyA3NzYKICAgIGRpZyAxMQogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGVjXzEgLy8gVE1QTF9WRVJJRklDQVRJT05fS0VZCiAgICB1bmNvdmVyIDMKICAgIGRpZyAyCiAgICBzdWJzdHJpbmczCiAgICBidG9pCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMTMKICAgIC8vIG5QdWJsaWM6IG9wLmJ0b2kodmtCeXRlcy5zbGljZSg3NzYsIDc4NCkpLAogICAgaW50YyAxMiAvLyA3ODQKICAgIGRpZyAxMQogICAgPj0KICAgIGludGMgMTIgLy8gNzg0CiAgICBkaWcgMTIKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAzCiAgICBkaWcgMgogICAgc3Vic3RyaW5nMwogICAgYnRvaQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzE0CiAgICAvLyBrMTogb3AuYnRvaSh2a0J5dGVzLnNsaWNlKDc4NCwgNzkyKSksCiAgICBpbnRjIDEzIC8vIDc5MgogICAgZGlnIDEyCiAgICA+PQogICAgaW50YyAxMyAvLyA3OTIKICAgIGRpZyAxMwogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGVjXzEgLy8gVE1QTF9WRVJJRklDQVRJT05fS0VZCiAgICB1bmNvdmVyIDMKICAgIGRpZyAyCiAgICBzdWJzdHJpbmczCiAgICBidG9pCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMTUKICAgIC8vIGsyOiBvcC5idG9pKHZrQnl0ZXMuc2xpY2UoNzkyLCA4MDApKSwKICAgIGludGMgMTQgLy8gODAwCiAgICBkaWcgMTMKICAgID49CiAgICBpbnRjIDE0IC8vIDgwMAogICAgZGlnIDE0CiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgYnl0ZWNfMSAvLyBUTVBMX1ZFUklGSUNBVElPTl9LRVkKICAgIHVuY292ZXIgMwogICAgZGlnIDIKICAgIHN1YnN0cmluZzMKICAgIGJ0b2kKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMxNgogICAgLy8gWF8yOiB2a0J5dGVzLnNsaWNlKDgwMCwgOTkyKS50b0ZpeGVkKHsgbGVuZ3RoOiAxOTIgfSksCiAgICBpbnRjIDE1IC8vIDk5MgogICAgZGlnIDE0CiAgICA+PQogICAgaW50YyAxNSAvLyA5OTIKICAgIHVuY292ZXIgMTUKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlY18xIC8vIFRNUExfVkVSSUZJQ0FUSU9OX0tFWQogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgbGVuCiAgICBpbnRjIDUgLy8gMTkyCiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDE5MgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzAzLTMxNwogICAgLy8gY29uc3Qgdms6IFZlcmlmaWNhdGlvbktleSA9IHsKICAgIC8vICAgUW06IHZrQnl0ZXMuc2xpY2UoMCwgOTYpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgLy8gICBRbDogdmtCeXRlcy5zbGljZSg5NiwgMTkyKS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIC8vICAgUXI6IHZrQnl0ZXMuc2xpY2UoMTkyLCAyODgpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgLy8gICBRbzogdmtCeXRlcy5zbGljZSgyODgsIDM4NCkudG9GaXhlZCh7IGxlbmd0aDogOTYgfSksCiAgICAvLyAgIFFjOiB2a0J5dGVzLnNsaWNlKDM4NCwgNDgwKS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIC8vICAgUzE6IHZrQnl0ZXMuc2xpY2UoNDgwLCA1NzYpLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLAogICAgLy8gICBTMjogdmtCeXRlcy5zbGljZSg1NzYsIDY3MikudG9GaXhlZCh7IGxlbmd0aDogOTYgfSksCiAgICAvLyAgIFMzOiB2a0J5dGVzLnNsaWNlKDY3MiwgNzY4KS50b0ZpeGVkKHsgbGVuZ3RoOiA5NiB9KSwKICAgIC8vICAgcG93ZXI6IG9wLmJ0b2kodmtCeXRlcy5zbGljZSg3NjgsIDc3NikpLAogICAgLy8gICBuUHVibGljOiBvcC5idG9pKHZrQnl0ZXMuc2xpY2UoNzc2LCA3ODQpKSwKICAgIC8vICAgazE6IG9wLmJ0b2kodmtCeXRlcy5zbGljZSg3ODQsIDc5MikpLAogICAgLy8gICBrMjogb3AuYnRvaSh2a0J5dGVzLnNsaWNlKDc5MiwgODAwKSksCiAgICAvLyAgIFhfMjogdmtCeXRlcy5zbGljZSg4MDAsIDk5MikudG9GaXhlZCh7IGxlbmd0aDogMTkyIH0pLAogICAgLy8gfTsKICAgIHVuY292ZXIgMTIKICAgIHVuY292ZXIgMTIKICAgIGNvbmNhdAogICAgdW5jb3ZlciAxMQogICAgY29uY2F0CiAgICB1bmNvdmVyIDEwCiAgICBjb25jYXQKICAgIHVuY292ZXIgOQogICAgY29uY2F0CiAgICB1bmNvdmVyIDgKICAgIGNvbmNhdAogICAgdW5jb3ZlciA3CiAgICBjb25jYXQKICAgIHVuY292ZXIgNgogICAgY29uY2F0CiAgICB1bmNvdmVyIDUKICAgIGl0b2IKICAgIGNvbmNhdAogICAgdW5jb3ZlciA0CiAgICBpdG9iCiAgICBjb25jYXQKICAgIHVuY292ZXIgMwogICAgaXRvYgogICAgY29uY2F0CiAgICB1bmNvdmVyIDIKICAgIGl0b2IKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBkdXBuIDIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM5NAogICAgLy8gbGV0IHRkID0gb3AuY29uY2F0KHZrLlFtLCB2ay5RbCk7CiAgICBleHRyYWN0IDAgOTYKICAgIGRpZyAxCiAgICBleHRyYWN0IDk2IDk2CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM5NQogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHZrLlFyKTsKICAgIGRpZyAxCiAgICBleHRyYWN0IDE5MiA5NgogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozOTYKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCB2ay5Rbyk7CiAgICBkaWcgMQogICAgaW50YyA2IC8vIDI4OAogICAgaW50Y18wIC8vIDk2CiAgICBleHRyYWN0MwogICAgY29uY2F0CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM5NwogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHZrLlFjKTsKICAgIGRpZyAxCiAgICBpbnRjIDQgLy8gMzg0CiAgICBpbnRjXzAgLy8gOTYKICAgIGV4dHJhY3QzCiAgICBkdXAKICAgIGNvdmVyIDMKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6Mzk4CiAgICAvLyB0ZCA9IG9wLmNvbmNhdCh0ZCwgdmsuUzEpOwogICAgZGlnIDEKICAgIGludGMgNyAvLyA0ODAKICAgIGludGNfMCAvLyA5NgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgY292ZXIgMwogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozOTkKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCB2ay5TMik7CiAgICBkaWcgMQogICAgaW50YyA4IC8vIDU3NgogICAgaW50Y18wIC8vIDk2CiAgICBleHRyYWN0MwogICAgZHVwCiAgICBjb3ZlciAzCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQwMAogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHZrLlMzKTsKICAgIHN3YXAKICAgIGludGMgOSAvLyA2NzIKICAgIGludGNfMCAvLyA5NgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgY292ZXIgMgogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0MDIKICAgIC8vIGZvciAoY29uc3Qgc2lnbmFsIG9mIHNpZ25hbHMpIHsKICAgIGZyYW1lX2RpZyAtMgogICAgaW50Y18zIC8vIDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnRjXzMgLy8gMAoKdmVyaWZ5X2Zvcl9oZWFkZXJAMjoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQwMgogICAgLy8gZm9yIChjb25zdCBzaWduYWwgb2Ygc2lnbmFscykgewogICAgZnJhbWVfZGlnIDQ3CiAgICBmcmFtZV9kaWcgNDYKICAgIDwKICAgIGJ6IHZlcmlmeV9hZnRlcl9mb3JANAogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDQ3CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludGNfMSAvLyAzMgogICAgKgogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE1OAogICAgLy8gcmV0dXJuIGEgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQwMwogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIGIzMihmclNjYWxhcihzaWduYWwubmF0aXZlKSkpOwogICAgY2FsbHN1YiBiMzIKICAgIGZyYW1lX2RpZyA0NQogICAgc3dhcAogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDQ1CiAgICBpbnRjXzIgLy8gMQogICAgKwogICAgZnJhbWVfYnVyeSA0NwogICAgYiB2ZXJpZnlfZm9yX2hlYWRlckAyCgp2ZXJpZnlfYWZ0ZXJfZm9yQDQ6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0MDcKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCBwcm9vZi5BKTsKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAwIDk2CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgOQogICAgZnJhbWVfZGlnIDQ1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQwOAogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLkIpOwogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDk2IDk2CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMTAKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDA5CiAgICAvLyB0ZCA9IG9wLmNvbmNhdCh0ZCwgcHJvb2YuQyk7CiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMTkyIDk2CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgNQogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0MTEKICAgIC8vIGNvbnN0IGJldGEgPSBnZXRDaGFsbGVuZ2UodGQpOwogICAgY2FsbHN1YiBnZXRDaGFsbGVuZ2UKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQxNgogICAgLy8gY29uc3QgZ2FtbWEgPSBnZXRDaGFsbGVuZ2UodGQpOwogICAgZHVwCiAgICBjYWxsc3ViIGdldENoYWxsZW5nZQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDIzCiAgICAvLyB0ZCA9IG9wLmNvbmNhdCh0ZCwgZ2FtbWEuYnl0ZXMpOwogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgNDUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQyNAogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLlopOwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjIDYgLy8gMjg4CiAgICBpbnRjXzAgLy8gOTYKICAgIGV4dHJhY3QzCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMjMKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDI1CiAgICAvLyBjb25zdCBhbHBoYSA9IGdldENoYWxsZW5nZSh0ZCk7CiAgICBjYWxsc3ViIGdldENoYWxsZW5nZQogICAgZHVwCiAgICBmcmFtZV9idXJ5IDExCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0MzIKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCBwcm9vZi5UMSk7CiAgICBmcmFtZV9kaWcgLTEKICAgIGludGMgNCAvLyAzODQKICAgIGludGNfMCAvLyA5NgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgZnJhbWVfYnVyeSA2CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQzMwogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLlQyKTsKICAgIGZyYW1lX2RpZyAtMQogICAgaW50YyA3IC8vIDQ4MAogICAgaW50Y18wIC8vIDk2CiAgICBleHRyYWN0MwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDcKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDM0CiAgICAvLyB0ZCA9IG9wLmNvbmNhdCh0ZCwgcHJvb2YuVDMpOwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjIDggLy8gNTc2CiAgICBpbnRjXzAgLy8gOTYKICAgIGV4dHJhY3QzCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgOAogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0MzUKICAgIC8vIGNvbnN0IHhpID0gZ2V0Q2hhbGxlbmdlKHRkKTsKICAgIGNhbGxzdWIgZ2V0Q2hhbGxlbmdlCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMzIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ0MgogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLmV2YWxfYS5ieXRlcyk7CiAgICBmcmFtZV9kaWcgLTEKICAgIHB1c2hpbnQgODY0IC8vIDg2NAogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDE4CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ0MwogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLmV2YWxfYi5ieXRlcyk7CiAgICBmcmFtZV9kaWcgLTEKICAgIHB1c2hpbnQgODk2IC8vIDg5NgogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDE5CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ0NAogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLmV2YWxfYy5ieXRlcyk7CiAgICBmcmFtZV9kaWcgLTEKICAgIHB1c2hpbnQgOTI4IC8vIDkyOAogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDIwCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ0NQogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLmV2YWxfczEuYnl0ZXMpOwogICAgZnJhbWVfZGlnIC0xCiAgICBwdXNoaW50IDk2MCAvLyA5NjAKICAgIGludGNfMSAvLyAzMgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAxNQogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NDYKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCBwcm9vZi5ldmFsX3MyLmJ5dGVzKTsKICAgIGZyYW1lX2RpZyAtMQogICAgaW50YyAxNSAvLyA5OTIKICAgIGludGNfMSAvLyAzMgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAxMwogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NDcKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCBwcm9vZi5ldmFsX3p3LmJ5dGVzKTsKICAgIGZyYW1lX2RpZyAtMQogICAgcHVzaGludCAxMDI0IC8vIDEwMjQKICAgIGludGNfMSAvLyAzMgogICAgZXh0cmFjdDMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAxNAogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NDkKICAgIC8vIGNvbnN0IHYgPSBuZXcgRml4ZWRBcnJheTxVaW50MjU2LCA2PigpOwogICAgaW50YyA1IC8vIDE5MgogICAgYnplcm8KICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ1MAogICAgLy8gdlsxXSA9IGdldENoYWxsZW5nZSh0ZCk7IC8vIHYxCiAgICBzd2FwCiAgICBjYWxsc3ViIGdldENoYWxsZW5nZQogICAgcmVwbGFjZTIgMzIgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9idXJ5IDMwCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NTEKICAgIC8vIGZvciAobGV0IGk6IHVpbnQ2NCA9IDI7IGkgPCA2OyBpKyspIHsKICAgIHB1c2hpbnQgMiAvLyAyCiAgICBmcmFtZV9idXJ5IDM1Cgp2ZXJpZnlfd2hpbGVfdG9wQDU6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NTEKICAgIC8vIGZvciAobGV0IGk6IHVpbnQ2NCA9IDI7IGkgPCA2OyBpKyspIHsKICAgIGZyYW1lX2RpZyAzNQogICAgcHVzaGludCA2IC8vIDYKICAgIDwKICAgIGJ6IHZlcmlmeV9hZnRlcl93aGlsZUA3CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NTIKICAgIC8vIHZbaV0gPSBuZXcgVWludDI1Nihmck11bCgodltpIC0gMV0gYXMgVWludDI1NikubmF0aXZlLCB2WzFdLm5hdGl2ZSkpOyAvLyB2W2ldID0gdjFeaQogICAgZnJhbWVfZGlnIDM1CiAgICBkdXAKICAgIGludGNfMiAvLyAxCiAgICAtCiAgICBpbnRjXzEgLy8gMzIKICAgICoKICAgIGZyYW1lX2RpZyAzMAogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIGludGNfMSAvLyAzMgogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkaWcgMQogICAgZXh0cmFjdCAzMiAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ1MgogICAgLy8gdltpXSA9IG5ldyBVaW50MjU2KGZyTXVsKCh2W2kgLSAxXSBhcyBVaW50MjU2KS5uYXRpdmUsIHZbMV0ubmF0aXZlKSk7IC8vIHZbaV0gPSB2MV5pCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18xIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBpbnRjXzEgLy8gMzIKICAgIGJ6ZXJvCiAgICBifAogICAgZGlnIDIKICAgIGludGNfMSAvLyAzMgogICAgKgogICAgc3dhcAogICAgcmVwbGFjZTMgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9idXJ5IDMwCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NTEKICAgIC8vIGZvciAobGV0IGk6IHVpbnQ2NCA9IDI7IGkgPCA2OyBpKyspIHsKICAgIGludGNfMiAvLyAxCiAgICArCiAgICBmcmFtZV9idXJ5IDM1CiAgICBiIHZlcmlmeV93aGlsZV90b3BANQoKdmVyaWZ5X2FmdGVyX3doaWxlQDc6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NTkKICAgIC8vIHRkID0gb3AuY29uY2F0KHRkLCBwcm9vZi5XeGkpOwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjIDkgLy8gNjcyCiAgICBpbnRjXzAgLy8gOTYKICAgIGV4dHJhY3QzCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMjgKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ2MAogICAgLy8gdGQgPSBvcC5jb25jYXQodGQsIHByb29mLld4aXcpOwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnRjIDEwIC8vIDc2OAogICAgaW50Y18wIC8vIDk2CiAgICBleHRyYWN0MwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDI0CiAgICBjb25jYXQKICAgIGR1cAogICAgZnJhbWVfYnVyeSAyOQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDYxCiAgICAvLyBjb25zdCB1ID0gZ2V0Q2hhbGxlbmdlKHRkKTsKICAgIGNhbGxzdWIgZ2V0Q2hhbGxlbmdlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0NjMtNDcyCiAgICAvLyByZXR1cm4gewogICAgLy8gICBiZXRhLAogICAgLy8gICBnYW1tYSwKICAgIC8vICAgYWxwaGEsCiAgICAvLyAgIHhpLAogICAgLy8gICB2LAogICAgLy8gICB1LAogICAgLy8gICB4aW46IG5ldyBVaW50MjU2KCksCiAgICAvLyAgIHpoOiBuZXcgVWludDI1NigpLAogICAgLy8gfTsKICAgIGZyYW1lX2RpZyA0NQogICAgZnJhbWVfZGlnIDExCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAzMgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgMzAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBwdXNoYnl0ZXMgMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAogICAgY29uY2F0CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMzMgogICAgLy8gZGVidWdMb2coImJldGEiLCBjaGFsbGVuZ2VzLmJldGEuYnl0ZXMpOwogICAgZHVwCiAgICBleHRyYWN0IDAgMzIKICAgIHB1c2hieXRlcyAiYmV0YSIKICAgIHN3YXAKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjMzMwogICAgLy8gZGVidWdMb2coImdhbW1hIiwgY2hhbGxlbmdlcy5nYW1tYS5ieXRlcyk7CiAgICBkdXAKICAgIGV4dHJhY3QgMzIgMzIKICAgIHB1c2hieXRlcyAiZ2FtbWEiCiAgICBzd2FwCiAgICBjYWxsc3ViIGRlYnVnTG9nCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMzQKICAgIC8vIGRlYnVnTG9nKCJhbHBoYSIsIGNoYWxsZW5nZXMuYWxwaGEuYnl0ZXMpOwogICAgZHVwCiAgICBleHRyYWN0IDY0IDMyCiAgICBwdXNoYnl0ZXMgImFscGhhIgogICAgc3dhcAogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzM1CiAgICAvLyBkZWJ1Z0xvZygieGkiLCBjaGFsbGVuZ2VzLnhpLmJ5dGVzKTsKICAgIGR1cAogICAgZXh0cmFjdCA5NiAzMgogICAgZHVwCiAgICBmcmFtZV9idXJ5IDMzCiAgICBwdXNoYnl0ZXMgInhpIgogICAgc3dhcAogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzM2CiAgICAvLyBkZWJ1Z0xvZygidSIsIGNoYWxsZW5nZXMudS5ieXRlcyk7CiAgICBkdXAKICAgIHB1c2hpbnQgMzIwIC8vIDMyMAogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgcHVzaGJ5dGVzICJ1IgogICAgc3dhcAogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzM3CiAgICAvLyBkZWJ1Z0xvZygieGluIiwgY2hhbGxlbmdlcy54aW4uYnl0ZXMpOwogICAgZHVwCiAgICBpbnRjIDE2IC8vIDM1MgogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgcHVzaGJ5dGVzICJ4aW4iCiAgICBzd2FwCiAgICBjYWxsc3ViIGRlYnVnTG9nCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMzgKICAgIC8vIGRlYnVnTG9nKCJ6aCIsIGNoYWxsZW5nZXMuemguYnl0ZXMpOwogICAgZHVwCiAgICBpbnRjIDQgLy8gMzg0CiAgICBpbnRjXzEgLy8gMzIKICAgIGV4dHJhY3QzCiAgICBwdXNoYnl0ZXMgInpoIgogICAgc3dhcAogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzM5CiAgICAvLyBkZWJ1Z0xvZygidlsxXSIsIChjaGFsbGVuZ2VzLnZbMV0gYXMgVWludDI1NikuYnl0ZXMpOwogICAgZXh0cmFjdCAxMjggMTkyCiAgICBkdXAKICAgIGV4dHJhY3QgMzIgMzIgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBwdXNoYnl0ZXMgInZbMV0iCiAgICBzd2FwCiAgICBjYWxsc3ViIGRlYnVnTG9nCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozMzktMzQwCiAgICAvLyBkZWJ1Z0xvZygidlsxXSIsIChjaGFsbGVuZ2VzLnZbMV0gYXMgVWludDI1NikuYnl0ZXMpOwogICAgLy8gZGVidWdMb2coInZbMl0iLCAoY2hhbGxlbmdlcy52WzJdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIGR1cAogICAgZXh0cmFjdCA2NCAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM0MAogICAgLy8gZGVidWdMb2coInZbMl0iLCAoY2hhbGxlbmdlcy52WzJdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIHB1c2hieXRlcyAidlsyXSIKICAgIHN3YXAKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM0MQogICAgLy8gZGVidWdMb2coInZbM10iLCAoY2hhbGxlbmdlcy52WzNdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIGR1cAogICAgZXh0cmFjdCA5NiAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHB1c2hieXRlcyAidlszXSIKICAgIHN3YXAKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM0MgogICAgLy8gZGVidWdMb2coInZbNF0iLCAoY2hhbGxlbmdlcy52WzRdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIGR1cAogICAgZXh0cmFjdCAxMjggMzIgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBwdXNoYnl0ZXMgInZbNF0iCiAgICBzd2FwCiAgICBjYWxsc3ViIGRlYnVnTG9nCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNDMKICAgIC8vIGRlYnVnTG9nKCJ2WzVdIiwgKGNoYWxsZW5nZXMudls1XSBhcyBVaW50MjU2KS5ieXRlcyk7CiAgICBleHRyYWN0IDE2MCAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHB1c2hieXRlcyAidls1XSIKICAgIHN3YXAKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ4NgogICAgLy8gbGV0IGRvbWFpblNpemU6IHVpbnQ2NCA9IDE7CiAgICBpbnRjXzIgLy8gMQogICAgZnJhbWVfYnVyeSAzNAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDg3CiAgICAvLyBmb3IgKGxldCBpOiB1aW50NjQgPSAwOyBpIDwgdmsucG93ZXI7IGkrKykgewogICAgaW50Y18zIC8vIDAKICAgIGZyYW1lX2J1cnkgMzUKCnZlcmlmeV93aGlsZV90b3BAMTA6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0ODcKICAgIC8vIGZvciAobGV0IGk6IHVpbnQ2NCA9IDA7IGkgPCB2ay5wb3dlcjsgaSsrKSB7CiAgICBmcmFtZV9kaWcgMzkKICAgIGludGMgMTAgLy8gNzY4CiAgICBleHRyYWN0X3VpbnQ2NAogICAgZnJhbWVfZGlnIDM1CiAgICA+CiAgICBieiB2ZXJpZnlfYWZ0ZXJfd2hpbGVAMTIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGZyYW1lX2RpZyAzMwogICAgZHVwCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICBmcmFtZV9idXJ5IDMzCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0ODkKICAgIC8vIGRvbWFpblNpemUgKj0gMjsKICAgIGZyYW1lX2RpZyAzNAogICAgcHVzaGludCAyIC8vIDIKICAgICoKICAgIGZyYW1lX2J1cnkgMzQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjQ4NwogICAgLy8gZm9yIChsZXQgaTogdWludDY0ID0gMDsgaSA8IHZrLnBvd2VyOyBpKyspIHsKICAgIGZyYW1lX2RpZyAzNQogICAgaW50Y18yIC8vIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMzUKICAgIGIgdmVyaWZ5X3doaWxlX3RvcEAxMAoKdmVyaWZ5X2FmdGVyX3doaWxlQDEyOgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDkyCiAgICAvLyBjaGFsbGVuZ2VzLnhpbiA9IG5ldyBVaW50MjU2KHhpbik7CiAgICBmcmFtZV9kaWcgMzMKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzEgLy8gMzIKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIGludGNfMSAvLyAzMgogICAgYnplcm8KICAgIGR1cAogICAgZnJhbWVfYnVyeSAzCiAgICBkdXAyCiAgICBifAogICAgZnJhbWVfZGlnIDE2CiAgICBpbnRjIDE2IC8vIDM1MgogICAgdW5jb3ZlciAyCiAgICByZXBsYWNlMwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NDkzCiAgICAvLyBjaGFsbGVuZ2VzLnpoID0gbmV3IFVpbnQyNTYoZnJTdWIoeGluLCBCaWdVaW50KDEpKSk7IC8vIFZhbmlzaGluZyBwb2x5bm9taWFsIFpfSCjOvikgPSDOvl5uIC0gMQogICAgdW5jb3ZlciAyCiAgICBieXRlY18zIC8vIDB4MDEKICAgIGNhbGxzdWIgZnJTdWIKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzEgLy8gMzIKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHVuY292ZXIgMgogICAgYnwKICAgIGludGMgNCAvLyAzODQKICAgIHN3YXAKICAgIHJlcGxhY2UzCiAgICBmcmFtZV9idXJ5IDE2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo0OTUKICAgIC8vIGNvbnN0IG4gPSBmclNjYWxhcihCaWdVaW50KGRvbWFpblNpemUpKTsKICAgIGZyYW1lX2RpZyAzNAogICAgaXRvYgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTU4CiAgICAvLyByZXR1cm4gYSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgZnJhbWVfYnVyeSAyMgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTAxCiAgICAvLyBsZXQgdyA9IEJpZ1VpbnQoMSk7CiAgICBieXRlY18zIC8vIDB4MDEKICAgIGZyYW1lX2J1cnkgMzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxMAogICAgLy8gY29uc3QgTDogVWludDI1NltdID0gW25ldyBVaW50MjU2KCldOwogICAgcHVzaGJ5dGVzIDB4MDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTEzCiAgICAvLyBjb25zdCBpdGVyYXRpb25zOiB1aW50NjQgPSB2ay5uUHVibGljID09PSAwID8gMSA6IHZrLm5QdWJsaWM7CiAgICBmcmFtZV9kaWcgMzkKICAgIGludGMgMTEgLy8gNzc2CiAgICBleHRyYWN0X3VpbnQ2NAogICAgZHVwCiAgICBmcmFtZV9idXJ5IDM4CiAgICBibnogdmVyaWZ5X3Rlcm5hcnlfZmFsc2VAMTQKICAgIGludGNfMiAvLyAxCiAgICBmcmFtZV9idXJ5IDM2Cgp2ZXJpZnlfdGVybmFyeV9tZXJnZUAxNToKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxNAogICAgLy8gZm9yIChsZXQgaTogdWludDY0ID0gMTsgaSA8PSBpdGVyYXRpb25zOyBpKyspIHsKICAgIGludGNfMiAvLyAxCiAgICBmcmFtZV9idXJ5IDM3Cgp2ZXJpZnlfd2hpbGVfdG9wQDE2OgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTE0CiAgICAvLyBmb3IgKGxldCBpOiB1aW50NjQgPSAxOyBpIDw9IGl0ZXJhdGlvbnM7IGkrKykgewogICAgZnJhbWVfZGlnIDM3CiAgICBmcmFtZV9kaWcgMzYKICAgIDw9CiAgICBieiB2ZXJpZnlfYWZ0ZXJfd2hpbGVAMjMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxOAogICAgLy8gZnJNdWwodywgY2hhbGxlbmdlcy56aC5uYXRpdmUpLAogICAgZnJhbWVfZGlnIDE2CiAgICBkdXAKICAgIGludGMgNCAvLyAzODQKICAgIGludGNfMSAvLyAzMgogICAgZXh0cmFjdDMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGZyYW1lX2RpZyAzMQogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxOQogICAgLy8gZnJNdWwobiwgZnJTdWIoY2hhbGxlbmdlcy54aS5uYXRpdmUsIHcpKSwKICAgIHVuY292ZXIgMgogICAgZXh0cmFjdCA5NiAzMgogICAgdW5jb3ZlciAyCiAgICBjYWxsc3ViIGZyU3ViCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBmcmFtZV9kaWcgMjIKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE1OAogICAgLy8gcmV0dXJuIGEgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGZyYW1lX2J1cnkgMQogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxMTEKICAgIC8vIGFzc2VydCh4ICE9PSAoMG4gYXMgYmlndWludCksICJGciBpbnZlcnNlIG9mIHplcm8iKTsKICAgIGR1cAogICAgYnl0ZWNfMiAvLyAweAogICAgYiE9CiAgICBhc3NlcnQgLy8gRnIgaW52ZXJzZSBvZiB6ZXJvCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxMTIKICAgIC8vIGNvbnN0IGludiA9IG1vZFBvdyh4LCBCTFMxMl8zODFfUl9NSU5VU18yLCByKTsKICAgIHB1c2hieXRlcyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZlZmZmZmZmZmYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjkwCiAgICAvLyBsZXQgcmVzdWx0ID0gMW4gYXMgYmlndWludDsKICAgIGJ5dGVjXzMgLy8gMHgwMQogICAgZnJhbWVfYnVyeSAyNgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTEKICAgIC8vIGxldCBiOiBiaWd1aW50ID0gYmFzZSAlIG1vZDsKICAgIHN3YXAKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjExMgogICAgLy8gY29uc3QgaW52ID0gbW9kUG93KHgsIEJMUzEyXzM4MV9SX01JTlVTXzIsIHIpOwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjkxCiAgICAvLyBsZXQgYjogYmlndWludCA9IGJhc2UgJSBtb2Q7CiAgICBiJQogICAgZnJhbWVfYnVyeSAxMgogICAgZnJhbWVfYnVyeSAxNwoKdmVyaWZ5X3doaWxlX3RvcEAxODoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjkzCiAgICAvLyB3aGlsZSAoZSA+ICgwbiBhcyBiaWd1aW50KSkgewogICAgZnJhbWVfZGlnIDE3CiAgICBieXRlY18yIC8vIDB4CiAgICBiPgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTMtOTkKICAgIC8vIHdoaWxlIChlID4gKDBuIGFzIGJpZ3VpbnQpKSB7CiAgICAvLyAgIGlmICgoZSAmICgxbiBhcyBiaWd1aW50KSkgIT09ICgwbiBhcyBiaWd1aW50KSkgewogICAgLy8gICAgIHJlc3VsdCA9IChyZXN1bHQgKiBiKSAlIG1vZDsKICAgIC8vICAgfQogICAgLy8gICBiID0gKGIgKiBiKSAlIG1vZDsKICAgIC8vICAgZSA9IGUgLyBCaWdVaW50KDIpOwogICAgLy8gfQogICAgYnogdmVyaWZ5X2FmdGVyX3doaWxlQDIyCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo5NAogICAgLy8gaWYgKChlICYgKDFuIGFzIGJpZ3VpbnQpKSAhPT0gKDBuIGFzIGJpZ3VpbnQpKSB7CiAgICBmcmFtZV9kaWcgMTcKICAgIGJ5dGVjXzMgLy8gMHgwMQogICAgYiYKICAgIGJ5dGVjXzIgLy8gMHgKICAgIGIhPQogICAgZnJhbWVfZGlnIDI2CiAgICBmcmFtZV9idXJ5IDI3CiAgICBieiB2ZXJpZnlfYWZ0ZXJfaWZfZWxzZUAyMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTUKICAgIC8vIHJlc3VsdCA9IChyZXN1bHQgKiBiKSAlIG1vZDsKICAgIGZyYW1lX2RpZyAyNgogICAgZnJhbWVfZGlnIDEyCiAgICBiKgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTEyCiAgICAvLyBjb25zdCBpbnYgPSBtb2RQb3coeCwgQkxTMTJfMzgxX1JfTUlOVVNfMiwgcik7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTUKICAgIC8vIHJlc3VsdCA9IChyZXN1bHQgKiBiKSAlIG1vZDsKICAgIGIlCiAgICBmcmFtZV9idXJ5IDI3Cgp2ZXJpZnlfYWZ0ZXJfaWZfZWxzZUAyMToKICAgIGZyYW1lX2RpZyAyNwogICAgZnJhbWVfYnVyeSAyNgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTcKICAgIC8vIGIgPSAoYiAqIGIpICUgbW9kOwogICAgZnJhbWVfZGlnIDEyCiAgICBkdXAKICAgIGIqCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxMTIKICAgIC8vIGNvbnN0IGludiA9IG1vZFBvdyh4LCBCTFMxMl8zODFfUl9NSU5VU18yLCByKTsKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo5NwogICAgLy8gYiA9IChiICogYikgJSBtb2Q7CiAgICBiJQogICAgZnJhbWVfYnVyeSAxMgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6OTgKICAgIC8vIGUgPSBlIC8gQmlnVWludCgyKTsKICAgIGZyYW1lX2RpZyAxNwogICAgcHVzaGJ5dGVzIDB4MDIKICAgIGIvCiAgICBmcmFtZV9idXJ5IDE3CiAgICBiIHZlcmlmeV93aGlsZV90b3BAMTgKCnZlcmlmeV9hZnRlcl93aGlsZUAyMjoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjEyNQogICAgLy8gcmV0dXJuIChhTiAqIGJJbnYpICUgcjsKICAgIGZyYW1lX2RpZyAxCiAgICBmcmFtZV9kaWcgMjYKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxNi01MjEKICAgIC8vIG5ldyBVaW50MjU2KAogICAgLy8gICBmckRpdigKICAgIC8vICAgICBmck11bCh3LCBjaGFsbGVuZ2VzLnpoLm5hdGl2ZSksCiAgICAvLyAgICAgZnJNdWwobiwgZnJTdWIoY2hhbGxlbmdlcy54aS5uYXRpdmUsIHcpKSwKICAgIC8vICAgKSwKICAgIC8vICksCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18xIC8vIDMyCiAgICA8PQogICAgYXNzZXJ0IC8vIG92ZXJmbG93CiAgICBmcmFtZV9kaWcgMwogICAgYnwKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxNS01MjIKICAgIC8vIEwucHVzaCgKICAgIC8vICAgbmV3IFVpbnQyNTYoCiAgICAvLyAgICAgZnJEaXYoCiAgICAvLyAgICAgICBmck11bCh3LCBjaGFsbGVuZ2VzLnpoLm5hdGl2ZSksCiAgICAvLyAgICAgICBmck11bChuLCBmclN1YihjaGFsbGVuZ2VzLnhpLm5hdGl2ZSwgdykpLAogICAgLy8gICAgICksCiAgICAvLyAgICksCiAgICAvLyApOwogICAgZnJhbWVfZGlnIDAKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQgLy8gb24gZXJyb3I6IG1heCBhcnJheSBsZW5ndGggZXhjZWVkZWQKICAgIHN3YXAKICAgIGludGNfMyAvLyAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50Y18yIC8vIDEKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICByZXBsYWNlMiAwCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGZyYW1lX2RpZyAzMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTIzCiAgICAvLyB3ID0gZnJNdWwodywgUk9PVF9PRl9VTklUWSk7IC8vIE5leHQgcm9vdCBvZiB1bml0eSBzdGVwICjPiV5pKQogICAgYnl0ZWMgNSAvLyBUTVBMX1JPT1RfT0ZfVU5JVFkKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGZyYW1lX2J1cnkgMzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUxNAogICAgLy8gZm9yIChsZXQgaTogdWludDY0ID0gMTsgaSA8PSBpdGVyYXRpb25zOyBpKyspIHsKICAgIGZyYW1lX2RpZyAzNwogICAgaW50Y18yIC8vIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMzcKICAgIGIgdmVyaWZ5X3doaWxlX3RvcEAxNgoKdmVyaWZ5X2FmdGVyX3doaWxlQDIzOgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTI1CiAgICAvLyByZXR1cm4geyBMLCBjaGFsbGVuZ2VzIH07CiAgICBwdXNoYnl0ZXMgMHgwMWEyCiAgICBmcmFtZV9kaWcgMTYKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIDAKICAgIGNvbmNhdAogICAgZHVwCiAgICBmcmFtZV9idXJ5IDQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM0Ni0zNTAKICAgIC8vIGNvbnN0IHsgTCwgY2hhbGxlbmdlczogdXBkYXRlZENoYWxsZW5nZXMgfSA9IGNhbGN1bGF0ZUxhZ3JhbmdlRXZhbHVhdGlvbnMoCiAgICAvLyAgIGNoYWxsZW5nZXMsCiAgICAvLyAgIHZrLAogICAgLy8gKTsKICAgIC8vIGRlYnVnTG9nKCJMMSh4aSkiLCAoTFsxXSBhcyBVaW50MjU2KS5ieXRlcyk7CiAgICBkdXAKICAgIGludGNfMyAvLyAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZGlnIDEKICAgIGxlbgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfYnVyeSAyCiAgICBleHRyYWN0IDM0IDMyCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMjEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM1MAogICAgLy8gZGVidWdMb2coIkwxKHhpKSIsIChMWzFdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIHB1c2hieXRlcyAiTDEoeGkpIgogICAgc3dhcAogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTM1CiAgICAvLyBsZXQgcGkgPSBCaWdVaW50KDApOwogICAgYnl0ZWNfMiAvLyAweAogICAgZnJhbWVfYnVyeSAyNQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTM2CiAgICAvLyBmb3IgKGxldCBpOiB1aW50NjQgPSAwOyBpIDwgcHVibGljU2lnbmFscy5sZW5ndGg7IGkrKykgewogICAgaW50Y18zIC8vIDAKICAgIGZyYW1lX2J1cnkgMzUKCnZlcmlmeV93aGlsZV90b3BAMjY6CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo1MzYKICAgIC8vIGZvciAobGV0IGk6IHVpbnQ2NCA9IDA7IGkgPCBwdWJsaWNTaWduYWxzLmxlbmd0aDsgaSsrKSB7CiAgICBmcmFtZV9kaWcgMzUKICAgIGZyYW1lX2RpZyA0NgogICAgPAogICAgYnogdmVyaWZ5X2FmdGVyX3doaWxlQDI4CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo1MzcKICAgIC8vIGNvbnN0IHcgPSBmclNjYWxhcigocHVibGljU2lnbmFsc1tpXSBhcyBVaW50MjU2KS5uYXRpdmUpOwogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDM1CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludGNfMSAvLyAzMgogICAgKgogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE1OAogICAgLy8gcmV0dXJuIGEgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUzOAogICAgLy8gcGkgPSBmclN1YihwaSwgZnJNdWwodywgKExbaSArIDFdIGFzIFVpbnQyNTYpLm5hdGl2ZSkpOwogICAgc3dhcAogICAgaW50Y18yIC8vIDEKICAgICsKICAgIGR1cAogICAgZnJhbWVfYnVyeSAzNQogICAgaW50Y18xIC8vIDMyCiAgICAqCiAgICBmcmFtZV9kaWcgMgogICAgc3dhcAogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjUzOAogICAgLy8gcGkgPSBmclN1YihwaSwgZnJNdWwodywgKExbaSArIDFdIGFzIFVpbnQyNTYpLm5hdGl2ZSkpOwogICAgZnJhbWVfZGlnIDI1CiAgICBzd2FwCiAgICBjYWxsc3ViIGZyU3ViCiAgICBmcmFtZV9idXJ5IDI1CiAgICBiIHZlcmlmeV93aGlsZV90b3BAMjYKCnZlcmlmeV9hZnRlcl93aGlsZUAyODoKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjU0MAogICAgLy8gcmV0dXJuIG5ldyBVaW50MjU2KHBpKTsKICAgIGZyYW1lX2RpZyAyNQogICAgZHVwCiAgICBsZW4KICAgIGludGNfMSAvLyAzMgogICAgPD0KICAgIGFzc2VydCAvLyBvdmVyZmxvdwogICAgZnJhbWVfZGlnIDMKICAgIGR1cAogICAgY292ZXIgMgogICAgYnwKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM1NQogICAgLy8gZGVidWdMb2coIlBJKHhpKSIsIHBpLmJ5dGVzKTsKICAgIHB1c2hieXRlcyAiUEkoeGkpIgogICAgZGlnIDEKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjU2MQogICAgLy8gZnJNdWwoY2hhbGxlbmdlcy5hbHBoYS5uYXRpdmUsIGNoYWxsZW5nZXMuYWxwaGEubmF0aXZlKSwKICAgIGZyYW1lX2RpZyA0CiAgICBwdXNoaW50cyAyIDQxNiAvLyAyLCA0MTYKICAgIGV4dHJhY3QzCiAgICBkdXAKICAgIGV4dHJhY3QgNjQgMzIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGR1cAogICAgZGlnIDEKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGZyYW1lX2RpZyAyMQogICAgYioKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTY4CiAgICAvLyBmck11bChjaGFsbGVuZ2VzLmJldGEubmF0aXZlLCBwcm9vZi5ldmFsX3MxLm5hdGl2ZSksCiAgICBkaWcgMgogICAgZXh0cmFjdCAwIDMyCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBkdXAKICAgIGZyYW1lX2RpZyAxNQogICAgZHVwCiAgICBjb3ZlciA4CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBmcmFtZV9kaWcgMTgKICAgIGR1cAogICAgY292ZXIgNgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IGJOOiBiaWd1aW50ID0gYiAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICBkaWcgMQogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NTcwCiAgICAvLyBlM2EgPSBmckFkZChlM2EsIGNoYWxsZW5nZXMuZ2FtbWEubmF0aXZlKTsKICAgIGRpZyA1CiAgICBleHRyYWN0IDMyIDMyCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIHN3YXAKICAgIGRpZyAxCiAgICBiKwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBkaWcgMwogICAgZnJhbWVfZGlnIDEzCiAgICBkdXAKICAgIGNvdmVyIDEyCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBmcmFtZV9kaWcgMTkKICAgIGR1cAogICAgY292ZXIgNAogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDgKICAgIC8vIGNvbnN0IGJOOiBiaWd1aW50ID0gYiAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICBkaWcgMQogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ3CiAgICAvLyBjb25zdCBhTjogYmlndWludCA9IGEgJSByOwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgZGlnIDMKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0NwogICAgLy8gY29uc3QgYU46IGJpZ3VpbnQgPSBhICUgcjsKICAgIGZyYW1lX2RpZyAyMAogICAgZHVwCiAgICBjb3ZlciAxMAogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgZHVwCiAgICBkaWcgNQogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQKICAgIC8vIHJldHVybiAoYSAqIGIpICUgQkxTMTJfMzgxX1NDQUxBUl9NT0RVTFVTOwogICAgdW5jb3ZlciA0CiAgICB1bmNvdmVyIDMKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICBmcmFtZV9kaWcgMTQKICAgIGR1cAogICAgY292ZXIgMTUKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGRpZyA5CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo1ODUKICAgIC8vIGNvbnN0IHIwID0gZnJTdWIoZnJTdWIoZTEsIGUyKSwgZTMpOwogICAgdW5jb3ZlciAxMwogICAgZGlnIDkKICAgIGNhbGxzdWIgZnJTdWIKICAgIHN3YXAKICAgIGNhbGxzdWIgZnJTdWIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjU4NgogICAgLy8gcmV0dXJuIG5ldyBVaW50MjU2KHIwKTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzEgLy8gMzIKICAgIDw9CiAgICBhc3NlcnQgLy8gb3ZlcmZsb3cKICAgIHVuY292ZXIgMTQKICAgIGJ8CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNTkKICAgIC8vIGRlYnVnTG9nKCJyMCIsIHIwLmJ5dGVzKTsKICAgIHB1c2hieXRlcyAicjAiCiAgICBkaWcgMQogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjEyCiAgICAvLyBkUG9pbnRzID0gb3AuY29uY2F0KGRQb2ludHMsIHByb29mLlQxKTsKICAgIGZyYW1lX2RpZyA0MAogICAgZnJhbWVfZGlnIDYKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjEzCiAgICAvLyBkUG9pbnRzID0gb3AuY29uY2F0KGRQb2ludHMsIHByb29mLlQyKTsKICAgIGZyYW1lX2RpZyA3CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYxNAogICAgLy8gZFBvaW50cyA9IG9wLmNvbmNhdChkUG9pbnRzLCBwcm9vZi5UMyk7CiAgICBmcmFtZV9kaWcgOAogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBkaWcgMTMKICAgIGRpZyA3CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2MjUKICAgIC8vIGZyTXVsKEJpZ1VpbnQoMSksIGNoYWxsZW5nZXMuemgubmF0aXZlKSwKICAgIGRpZyAxMwogICAgaW50YyA0IC8vIDM4NAogICAgaW50Y18xIC8vIDMyCiAgICBleHRyYWN0MwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQKICAgIC8vIHJldHVybiAoYSAqIGIpICUgQkxTMTJfMzgxX1NDQUxBUl9NT0RVTFVTOwogICAgZHVwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYyNAogICAgLy8gQmlnVWludCgwKSwKICAgIGJ5dGVjXzIgLy8gMHgKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYyMy02MjYKICAgIC8vIGNvbnN0IHF1b3RpZW50U2NhbGFyMSA9IGZyU3ViKAogICAgLy8gICBCaWdVaW50KDApLAogICAgLy8gICBmck11bChCaWdVaW50KDEpLCBjaGFsbGVuZ2VzLnpoLm5hdGl2ZSksCiAgICAvLyApOyAvLyAtVDEqemgKICAgIHN3YXAKICAgIGNhbGxzdWIgZnJTdWIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYyOQogICAgLy8gZnJNdWwoY2hhbGxlbmdlcy54aW4ubmF0aXZlLCBjaGFsbGVuZ2VzLnpoLm5hdGl2ZSksCiAgICBkaWcgMTUKICAgIGludGMgMTYgLy8gMzUyCiAgICBpbnRjXzEgLy8gMzIKICAgIGV4dHJhY3QzCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBkdXAKICAgIGRpZyAzCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2MjgKICAgIC8vIEJpZ1VpbnQoMCksCiAgICBieXRlY18yIC8vIDB4CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2MjctNjMwCiAgICAvLyBjb25zdCBxdW90aWVudFNjYWxhcjIgPSBmclN1YigKICAgIC8vICAgQmlnVWludCgwKSwKICAgIC8vICAgZnJNdWwoY2hhbGxlbmdlcy54aW4ubmF0aXZlLCBjaGFsbGVuZ2VzLnpoLm5hdGl2ZSksCiAgICAvLyApOyAvLyAtVDIqeGluKnpoCiAgICBzd2FwCiAgICBjYWxsc3ViIGZyU3ViCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBkaWcgMQogICAgdW5jb3ZlciAyCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICB1bmNvdmVyIDMKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYzMgogICAgLy8gQmlnVWludCgwKSwKICAgIGJ5dGVjXzIgLy8gMHgKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjYzMS02MzcKICAgIC8vIGNvbnN0IHF1b3RpZW50U2NhbGFyMyA9IGZyU3ViKAogICAgLy8gICBCaWdVaW50KDApLAogICAgLy8gICBmck11bCgKICAgIC8vICAgICBmck11bChjaGFsbGVuZ2VzLnhpbi5uYXRpdmUsIGNoYWxsZW5nZXMueGluLm5hdGl2ZSksCiAgICAvLyAgICAgY2hhbGxlbmdlcy56aC5uYXRpdmUsCiAgICAvLyAgICksCiAgICAvLyApOyAvLyAtVDMqeGluwrIqemgKICAgIHN3YXAKICAgIGNhbGxzdWIgZnJTdWIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0MAogICAgLy8gbGV0IGRTY2FsYXJzID0gb3AuY29uY2F0KGIzMihnYXRlU2NhbGFyMSksIGIzMihnYXRlU2NhbGFyMikpOwogICAgdW5jb3ZlciAzCiAgICBjYWxsc3ViIGIzMgogICAgZGlnIDE3CiAgICBjYWxsc3ViIGIzMgogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NDEKICAgIC8vIGRTY2FsYXJzID0gb3AuY29uY2F0KGRTY2FsYXJzLCBiMzIoZ2F0ZVNjYWxhcjMpKTsKICAgIGRpZyAxMAogICAgY2FsbHN1YiBiMzIKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQyCiAgICAvLyBkU2NhbGFycyA9IG9wLmNvbmNhdChkU2NhbGFycywgYjMyKGdhdGVTY2FsYXI0KSk7CiAgICBkaWcgMTUKICAgIGNhbGxzdWIgYjMyCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0MwogICAgLy8gZFNjYWxhcnMgPSBvcC5jb25jYXQoZFNjYWxhcnMsIGIzMihxdW90aWVudFNjYWxhcjEpKTsKICAgIHVuY292ZXIgMwogICAgY2FsbHN1YiBiMzIKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQ0CiAgICAvLyBkU2NhbGFycyA9IG9wLmNvbmNhdChkU2NhbGFycywgYjMyKHF1b3RpZW50U2NhbGFyMikpOwogICAgdW5jb3ZlciAyCiAgICBjYWxsc3ViIGIzMgogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NDUKICAgIC8vIGRTY2FsYXJzID0gb3AuY29uY2F0KGRTY2FsYXJzLCBiMzIocXVvdGllbnRTY2FsYXIzKSk7CiAgICBzd2FwCiAgICBjYWxsc3ViIGIzMgogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NDgtNjUyCiAgICAvLyBjb25zdCBkQmF0Y2hlZCA9IG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsTXVsdGkoCiAgICAvLyAgIG9wLkVjLkJMUzEyXzM4MWcxLAogICAgLy8gICBkUG9pbnRzLAogICAgLy8gICBkU2NhbGFycywKICAgIC8vICk7CiAgICBlY19tdWx0aV9zY2FsYXJfbXVsIEJMUzEyXzM4MWcxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NTMKICAgIC8vIGxldCBEID0gZzFBZGQoZEJhdGNoZWQudG9GaXhlZCh7IGxlbmd0aDogOTYgfSksIHZrLlFjKTsgLy8gQWRkIFFjIGNvbnN0YW50IHRlcm0KICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIzNgogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuYWRkKG9wLkVjLkJMUzEyXzM4MWcxLCBwMSwgcDIpLnRvRml4ZWQoewogICAgZnJhbWVfZGlnIDQxCiAgICBlY19hZGQgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIzNi0yMzgKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLmFkZChvcC5FYy5CTFMxMl8zODFnMSwgcDEsIHAyKS50b0ZpeGVkKHsKICAgIC8vICAgbGVuZ3RoOiA5NiwKICAgIC8vIH0pOwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjU2CiAgICAvLyBjb25zdCBiZXRheGkgPSBmck11bChjaGFsbGVuZ2VzLmJldGEubmF0aXZlLCBjaGFsbGVuZ2VzLnhpLm5hdGl2ZSk7CiAgICBkaWcgMTIKICAgIGV4dHJhY3QgOTYgMzIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGRpZyA5CiAgICBkaWcgMQogICAgYioKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ4CiAgICAvLyBjb25zdCBiTjogYmlndWludCA9IGIgJSByOwogICAgZHVwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICB1bmNvdmVyIDEwCiAgICBiKwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICBkaWcgOAogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjYyCiAgICAvLyBmckFkZChwcm9vZi5ldmFsX2IubmF0aXZlLCBmck11bChiZXRheGksIEJpZ1VpbnQodmsuazEpKSksCiAgICBmcmFtZV9kaWcgMzkKICAgIGR1cAogICAgY292ZXIgMwogICAgaW50YyAxMiAvLyA3ODQKICAgIHB1c2hpbnQgOCAvLyA4CiAgICBleHRyYWN0MwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQKICAgIC8vIHJldHVybiAoYSAqIGIpICUgQkxTMTJfMzgxX1NDQUxBUl9NT0RVTFVTOwogICAgZGlnIDIKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIHVuY292ZXIgOQogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ3CiAgICAvLyBjb25zdCBhTjogYmlndWludCA9IGEgJSByOwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgZGlnIDkKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY2NgogICAgLy8gZnJBZGQocHJvb2YuZXZhbF9jLm5hdGl2ZSwgZnJNdWwoYmV0YXhpLCBCaWdVaW50KHZrLmsyKSkpLAogICAgZGlnIDMKICAgIGludGMgMTMgLy8gNzkyCiAgICBwdXNoaW50IDggLy8gOAogICAgZXh0cmFjdDMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgMwogICAgYioKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ4CiAgICAvLyBjb25zdCBiTjogYmlndWludCA9IGIgJSByOwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgdW5jb3ZlciA4CiAgICBiKwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICB1bmNvdmVyIDgKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGNvdmVyIDIKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIGRpZyA5CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHVuY292ZXIgOAogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6Njc0CiAgICAvLyBjb25zdCB6U2NhbGFyID0gZnJBZGQoZnJBZGQoZDJhLCBkMmIpLCBjaGFsbGVuZ2VzLnUubmF0aXZlKTsKICAgIGRpZyAxMAogICAgcHVzaGludCAzMjAgLy8gMzIwCiAgICBpbnRjXzEgLy8gMzIKICAgIGV4dHJhY3QzCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIGRpZyAxCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OQogICAgLy8gcmV0dXJuIChhTiArIGJOKSAlIHI7CiAgICBiKwogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMjUKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgZnJhbWVfZGlnIDIzCiAgICBzd2FwCiAgICBlY19zY2FsYXJfbXVsIEJMUzEyXzM4MWcxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMjUtMjI3CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWwob3AuRWMuQkxTMTJfMzgxZzEsIHAsIEJ5dGVzKHMpKS50b0ZpeGVkKHsKICAgIC8vICAgbGVuZ3RoOiA5NiwKICAgIC8vIH0pOwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjM2CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5hZGQob3AuRWMuQkxTMTJfMzgxZzEsIHAxLCBwMikudG9GaXhlZCh7CiAgICB1bmNvdmVyIDQKICAgIHN3YXAKICAgIGVjX2FkZCBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjM2LTIzOAogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuYWRkKG9wLkVjLkJMUzEyXzM4MWcxLCBwMSwgcDIpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICB1bmNvdmVyIDgKICAgIHVuY292ZXIgOAogICAgYioKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgZGlnIDExCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICB1bmNvdmVyIDYKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNQogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsKG9wLkVjLkJMUzEyXzM4MWcxLCBwLCBCeXRlcyhzKSkudG9GaXhlZCh7CiAgICBmcmFtZV9kaWcgNDQKICAgIHN3YXAKICAgIGVjX3NjYWxhcl9tdWwgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNS0yMjcKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyNDcKICAgIC8vIHJldHVybiBnMVRpbWVzRnIocCwgUl9NSU5VU18xKTsKICAgIGJ5dGVjIDQgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAwCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMjUKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgZWNfc2NhbGFyX211bCBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1LTIyNwogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsKG9wLkVjLkJMUzEyXzM4MWcxLCBwLCBCeXRlcyhzKSkudG9GaXhlZCh7CiAgICAvLyAgIGxlbmd0aDogOTYsCiAgICAvLyB9KTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIzNgogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuYWRkKG9wLkVjLkJMUzEyXzM4MWcxLCBwMSwgcDIpLnRvRml4ZWQoewogICAgZWNfYWRkIEJMUzEyXzM4MWcxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMzYtMjM4CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5hZGQob3AuRWMuQkxTMTJfMzgxZzEsIHAxLCBwMikudG9GaXhlZCh7CiAgICAvLyAgIGxlbmd0aDogOTYsCiAgICAvLyB9KTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcwMwogICAgLy8gbGV0IGZQb2ludHMgPSBvcC5jb25jYXQocHJvb2YuQSwgcHJvb2YuQik7CiAgICBmcmFtZV9kaWcgOQogICAgZnJhbWVfZGlnIDEwCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcwNAogICAgLy8gZlBvaW50cyA9IG9wLmNvbmNhdChmUG9pbnRzLCBwcm9vZi5DKTsKICAgIGZyYW1lX2RpZyA1CiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcwNQogICAgLy8gZlBvaW50cyA9IG9wLmNvbmNhdChmUG9pbnRzLCB2ay5TMSk7CiAgICBmcmFtZV9kaWcgNDIKICAgIGNvbmNhdAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NzA2CiAgICAvLyBmUG9pbnRzID0gb3AuY29uY2F0KGZQb2ludHMsIHZrLlMyKTsKICAgIGZyYW1lX2RpZyA0MwogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo3MTAKICAgIC8vIChjaGFsbGVuZ2VzLnZbMV0gYXMgVWludDI1NikuYnl0ZXMsCiAgICB1bmNvdmVyIDgKICAgIGV4dHJhY3QgMTI4IDE5MgogICAgZHVwCiAgICBleHRyYWN0IDMyIDMyIC8vIG9uIGVycm9yOiBpbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NzEwLTcxMQogICAgLy8gKGNoYWxsZW5nZXMudlsxXSBhcyBVaW50MjU2KS5ieXRlcywKICAgIC8vIChjaGFsbGVuZ2VzLnZbMl0gYXMgVWludDI1NikuYnl0ZXMsCiAgICBkaWcgMQogICAgZXh0cmFjdCA2NCAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcwOS03MTIKICAgIC8vIGxldCBmU2NhbGFycyA9IG9wLmNvbmNhdCgKICAgIC8vICAgKGNoYWxsZW5nZXMudlsxXSBhcyBVaW50MjU2KS5ieXRlcywKICAgIC8vICAgKGNoYWxsZW5nZXMudlsyXSBhcyBVaW50MjU2KS5ieXRlcywKICAgIC8vICk7CiAgICBkdXAyCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcxMwogICAgLy8gZlNjYWxhcnMgPSBvcC5jb25jYXQoZlNjYWxhcnMsIChjaGFsbGVuZ2VzLnZbM10gYXMgVWludDI1NikuYnl0ZXMpOwogICAgZGlnIDMKICAgIGV4dHJhY3QgOTYgMzIgLy8gb24gZXJyb3I6IGluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBkaWcgMQogICAgY29uY2F0CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo3MTQKICAgIC8vIGZTY2FsYXJzID0gb3AuY29uY2F0KGZTY2FsYXJzLCAoY2hhbGxlbmdlcy52WzRdIGFzIFVpbnQyNTYpLmJ5dGVzKTsKICAgIGRpZyA0CiAgICBleHRyYWN0IDEyOCAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGRpZyAxCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcxNQogICAgLy8gZlNjYWxhcnMgPSBvcC5jb25jYXQoZlNjYWxhcnMsIChjaGFsbGVuZ2VzLnZbNV0gYXMgVWludDI1NikuYnl0ZXMpOwogICAgdW5jb3ZlciA1CiAgICBleHRyYWN0IDE2MCAzMiAvLyBvbiBlcnJvcjogaW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGRpZyAxCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcxNy03MjEKICAgIC8vIGNvbnN0IGZCYXRjaGVkID0gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWxNdWx0aSgKICAgIC8vICAgb3AuRWMuQkxTMTJfMzgxZzEsCiAgICAvLyAgIGZQb2ludHMsCiAgICAvLyAgIGZTY2FsYXJzLAogICAgLy8gKTsKICAgIHVuY292ZXIgNgogICAgc3dhcAogICAgZWNfbXVsdGlfc2NhbGFyX211bCBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NzIyCiAgICAvLyBjb25zdCBGID0gZzFBZGQoRCwgZkJhdGNoZWQudG9GaXhlZCh7IGxlbmd0aDogOTYgfSkpOwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjM2CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5hZGQob3AuRWMuQkxTMTJfMzgxZzEsIHAxLCBwMikudG9GaXhlZCh7CiAgICBkaWcgNgogICAgc3dhcAogICAgZWNfYWRkIEJMUzEyXzM4MWcxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMzYtMjM4CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5hZGQob3AuRWMuQkxTMTJfMzgxZzEsIHAxLCBwMikudG9GaXhlZCh7CiAgICAvLyAgIGxlbmd0aDogOTYsCiAgICAvLyB9KTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjcyNAogICAgLy8gcmV0dXJuIHsgRCwgRiB9OwogICAgdW5jb3ZlciA2CiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjM2MgogICAgLy8gY29uc3QgeyBEOiBkLCBGOiBmIH0gPSBjYWxjdWxhdGVERihwcm9vZiwgY2hhbGxlbmdlcywgdmssIExbMV0gYXMgVWludDI1Nik7CiAgICBkdXAKICAgIGV4dHJhY3QgMCA5NgogICAgc3dhcAogICAgZXh0cmFjdCA5NiA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MzYzCiAgICAvLyBkZWJ1Z0xvZygiRCIsIGQpOwogICAgcHVzaGJ5dGVzICJEIgogICAgdW5jb3ZlciAyCiAgICBjYWxsc3ViIGRlYnVnTG9nCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNjQKICAgIC8vIGRlYnVnTG9nKCJGIiwgZik7CiAgICBwdXNoYnl0ZXMgIkYiCiAgICBkaWcgMQogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NjQKICAgIC8vIHJldHVybiAoYSAqIGIpICUgQkxTMTJfMzgxX1NDQUxBUl9NT0RVTFVTOwogICAgdW5jb3ZlciA1CiAgICB1bmNvdmVyIDEyCiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo3MzgtNzQxCiAgICAvLyBsZXQgZSA9IGZyU3ViKAogICAgLy8gICBmck11bCgoY2hhbGxlbmdlcy52WzFdIGFzIFVpbnQyNTYpLm5hdGl2ZSwgcHJvb2YuZXZhbF9hLm5hdGl2ZSksCiAgICAvLyAgIHIwLm5hdGl2ZSwKICAgIC8vICk7CiAgICB1bmNvdmVyIDkKICAgIGNhbGxzdWIgZnJTdWIKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgNQogICAgdW5jb3ZlciA5CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgNAogICAgdW5jb3ZlciA4CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciA5CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgMgogICAgdW5jb3ZlciA3CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDcKICAgIC8vIGNvbnN0IGFOOiBiaWd1aW50ID0gYSAlIHI7CiAgICBzd2FwCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0OAogICAgLy8gY29uc3QgYk46IGJpZ3VpbnQgPSBiICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ5CiAgICAvLyByZXR1cm4gKGFOICsgYk4pICUgcjsKICAgIGIrCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIGRpZyAyCiAgICB1bmNvdmVyIDYKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjE0NwogICAgLy8gY29uc3QgYU46IGJpZ3VpbnQgPSBhICUgcjsKICAgIHN3YXAKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MTQ4CiAgICAvLyBjb25zdCBiTjogYmlndWludCA9IGIgJSByOwogICAgc3dhcAogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoxNDkKICAgIC8vIHJldHVybiAoYU4gKyBiTikgJSByOwogICAgYisKICAgIGJ5dGVjXzAgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAxCiAgICBiJQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6NzU0CiAgICAvLyBjb25zdCByZXMgPSBnMVRpbWVzRnIoRzFfT05FLnRvRml4ZWQoeyBsZW5ndGg6IDk2IH0pLCBlKTsKICAgIHB1c2hieXRlcyAweDE3ZjFkM2E3MzE5N2Q3OTQyNjk1NjM4YzRmYTlhYzBmYzM2ODhjNGY5Nzc0YjkwNWExNGUzYTNmMTcxYmFjNTg2YzU1ZTgzZmY5N2ExYWVmZmIzYWYwMGFkYjIyYzZiYjA4YjNmNDgxZTNhYWEwZjFhMDllMzBlZDc0MWQ4YWU0ZmNmNWUwOTVkNWQwMGFmNjAwZGIxOGNiMmMwNGIzZWRkMDNjYzc0NGEyODg4YWU0MGNhYTIzMjk0NmM1ZTdlMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWwob3AuRWMuQkxTMTJfMzgxZzEsIHAsIEJ5dGVzKHMpKS50b0ZpeGVkKHsKICAgIHN3YXAKICAgIGVjX3NjYWxhcl9tdWwgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNS0yMjcKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czozNjgKICAgIC8vIGRlYnVnTG9nKCJFIiwgZSk7CiAgICBwdXNoYnl0ZXMgIkUiCiAgICBkaWcgMQogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWwob3AuRWMuQkxTMTJfMzgxZzEsIHAsIEJ5dGVzKHMpKS50b0ZpeGVkKHsKICAgIGZyYW1lX2RpZyAyNAogICAgZGlnIDMKICAgIGVjX3NjYWxhcl9tdWwgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNS0yMjcKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMzYKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLmFkZChvcC5FYy5CTFMxMl8zODFnMSwgcDEsIHAyKS50b0ZpeGVkKHsKICAgIGZyYW1lX2RpZyAyOAogICAgc3dhcAogICAgZWNfYWRkIEJMUzEyXzM4MWcxCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMzYtMjM4CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5hZGQob3AuRWMuQkxTMTJfMzgxZzEsIHAxLCBwMikudG9GaXhlZCh7CiAgICAvLyAgIGxlbmd0aDogOTYsCiAgICAvLyB9KTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjY0CiAgICAvLyByZXR1cm4gKGEgKiBiKSAlIEJMUzEyXzM4MV9TQ0FMQVJfTU9EVUxVUzsKICAgIHVuY292ZXIgMwogICAgZGlnIDUKICAgIGIqCiAgICBieXRlY18wIC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMQogICAgYiUKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjc4NgogICAgLy8gUk9PVF9PRl9VTklUWSwKICAgIGJ5dGVjIDUgLy8gVE1QTF9ST09UX09GX1VOSVRZCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo2NAogICAgLy8gcmV0dXJuIChhICogYikgJSBCTFMxMl8zODFfU0NBTEFSX01PRFVMVVM7CiAgICBiKgogICAgYnl0ZWNfMCAvLyAweDczZWRhNzUzMjk5ZDdkNDgzMzM5ZDgwODA5YTFkODA1NTNiZGE0MDJmZmZlNWJmZWZmZmZmZmZmMDAwMDAwMDEKICAgIGIlCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo3ODgKICAgIC8vIGNvbnN0IHBhaXJpbmdTY2FsYXJzID0gb3AuY29uY2F0KGNoYWxsZW5nZXMueGkuYnl0ZXMsIGIzMihzKSk7CiAgICBjYWxsc3ViIGIzMgogICAgdW5jb3ZlciA1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjc5MC03OTQKICAgIC8vIGxldCBCMSA9IG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsTXVsdGkoCiAgICAvLyAgIG9wLkVjLkJMUzEyXzM4MWcxLAogICAgLy8gICBwYWlyaW5nUG9pbnRzLAogICAgLy8gICBwYWlyaW5nU2NhbGFycywKICAgIC8vICkudG9GaXhlZCh7IGxlbmd0aDogOTYgfSk7CiAgICBmcmFtZV9kaWcgMjkKICAgIHN3YXAKICAgIGVjX211bHRpX3NjYWxhcl9tdWwgQkxTMTJfMzgxZzEKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIzNgogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuYWRkKG9wLkVjLkJMUzEyXzM4MWcxLCBwMSwgcDIpLnRvRml4ZWQoewogICAgdW5jb3ZlciAzCiAgICBlY19hZGQgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIzNi0yMzgKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLmFkZChvcC5FYy5CTFMxMl8zODFnMSwgcDEsIHAyKS50b0ZpeGVkKHsKICAgIC8vICAgbGVuZ3RoOiA5NiwKICAgIC8vIH0pOwogICAgZHVwCiAgICBsZW4KICAgIGludGNfMCAvLyA5NgogICAgPT0KICAgIGFzc2VydCAvLyBMZW5ndGggbXVzdCBiZSA5NgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWwob3AuRWMuQkxTMTJfMzgxZzEsIHAsIEJ5dGVzKHMpKS50b0ZpeGVkKHsKICAgIHVuY292ZXIgMgogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjQ3CiAgICAvLyByZXR1cm4gZzFUaW1lc0ZyKHAsIFJfTUlOVVNfMSk7CiAgICBieXRlYyA0IC8vIDB4NzNlZGE3NTMyOTlkN2Q0ODMzMzlkODA4MDlhMWQ4MDU1M2JkYTQwMmZmZmU1YmZlZmZmZmZmZmYwMDAwMDAwMAogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1CiAgICAvLyByZXR1cm4gb3AuRWxsaXB0aWNDdXJ2ZS5zY2FsYXJNdWwob3AuRWMuQkxTMTJfMzgxZzEsIHAsIEJ5dGVzKHMpKS50b0ZpeGVkKHsKICAgIGVjX3NjYWxhcl9tdWwgQkxTMTJfMzgxZzEKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNS0yMjcKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMzYKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLmFkZChvcC5FYy5CTFMxMl8zODFnMSwgcDEsIHAyKS50b0ZpeGVkKHsKICAgIGVjX2FkZCBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjM2LTIzOAogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuYWRkKG9wLkVjLkJMUzEyXzM4MWcxLCBwMSwgcDIpLnRvRml4ZWQoewogICAgLy8gICBsZW5ndGg6IDk2LAogICAgLy8gfSk7CiAgICBkdXAKICAgIGxlbgogICAgaW50Y18wIC8vIDk2CiAgICA9PQogICAgYXNzZXJ0IC8vIExlbmd0aCBtdXN0IGJlIDk2CiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czo3OTgKICAgIC8vIGRlYnVnTG9nKCJBMSIsIEExKTsKICAgIHB1c2hieXRlcyAiQTEiCiAgICBkaWcgMgogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6Nzk5CiAgICAvLyBkZWJ1Z0xvZygiQjEiLCBCMSk7CiAgICBwdXNoYnl0ZXMgIkIxIgogICAgZGlnIDEKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjIyNQogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsKG9wLkVjLkJMUzEyXzM4MWcxLCBwLCBCeXRlcyhzKSkudG9GaXhlZCh7CiAgICBzd2FwCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyNDcKICAgIC8vIHJldHVybiBnMVRpbWVzRnIocCwgUl9NSU5VU18xKTsKICAgIGJ5dGVjIDQgLy8gMHg3M2VkYTc1MzI5OWQ3ZDQ4MzMzOWQ4MDgwOWExZDgwNTUzYmRhNDAyZmZmZTViZmVmZmZmZmZmZjAwMDAwMDAwCiAgICAvLyBjb250cmFjdHMvcGxvbmtfYmxzMTIzODEuYWxnby50czoyMjUKICAgIC8vIHJldHVybiBvcC5FbGxpcHRpY0N1cnZlLnNjYWxhck11bChvcC5FYy5CTFMxMl8zODFnMSwgcCwgQnl0ZXMocykpLnRvRml4ZWQoewogICAgZWNfc2NhbGFyX211bCBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6MjI1LTIyNwogICAgLy8gcmV0dXJuIG9wLkVsbGlwdGljQ3VydmUuc2NhbGFyTXVsKG9wLkVjLkJMUzEyXzM4MWcxLCBwLCBCeXRlcyhzKSkudG9GaXhlZCh7CiAgICAvLyAgIGxlbmd0aDogOTYsCiAgICAvLyB9KTsKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzAgLy8gOTYKICAgID09CiAgICBhc3NlcnQgLy8gTGVuZ3RoIG11c3QgYmUgOTYKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjgwMAogICAgLy8gZGVidWdMb2coIm5lZyhBMSkiLCBnMU5lZyhBMSkpOwogICAgcHVzaGJ5dGVzICJuZWcoQTEpIgogICAgZGlnIDEKICAgIGNhbGxzdWIgZGVidWdMb2cKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjgwMQogICAgLy8gZGVidWdMb2coInZrLlhfMiIsIHZrLlhfMik7CiAgICB1bmNvdmVyIDIKICAgIGludGMgMTQgLy8gODAwCiAgICBpbnRjIDUgLy8gMTkyCiAgICBleHRyYWN0MwogICAgcHVzaGJ5dGVzICJ2ay5YXzIiCiAgICBkaWcgMQogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6ODAyCiAgICAvLyBkZWJ1Z0xvZygiRzJfT05FIiwgRzJfT05FKTsKICAgIHB1c2hieXRlcyAiRzJfT05FIgogICAgYnl0ZWMgNiAvLyAweDAyNGFhMmIyZjA4ZjBhOTEyNjA4MDUyNzJkYzUxMDUxYzZlNDdhZDRmYTQwM2IwMmI0NTEwYjY0N2FlM2QxNzcwYmFjMDMyNmE4MDViYmVmZDQ4MDU2YzhjMTIxYmRiODEzZTAyYjYwNTI3MTlmNjA3ZGFjZDNhMDg4Mjc0ZjY1NTk2YmQwZDA5OTIwYjYxYWI1ZGE2MWJiZGM3ZjUwNDkzMzRjZjExMjEzOTQ1ZDU3ZTVhYzdkMDU1ZDA0MmI3ZTBjZTVkNTI3NzI3ZDZlMTE4Y2M5Y2RjNmRhMmUzNTFhYWRmZDliYWE4Y2JkZDNhNzZkNDI5YTY5NTE2MGQxMmM5MjNhYzljYzNiYWNhMjg5ZTE5MzU0ODYwOGI4MjgwMTA2MDZjNGEwMmVhNzM0Y2MzMmFjZDJiMDJiYzI4Yjk5Y2IzZTI4N2U4NWE3NjNhZjI2NzQ5MmFiNTcyZTk5YWIzZjM3MGQyNzVjZWMxZGExYWFhOTA3NWZmMDVmNzliZQogICAgY2FsbHN1YiBkZWJ1Z0xvZwogICAgLy8gY29udHJhY3RzL3Bsb25rX2JsczEyMzgxLmFsZ28udHM6ODA3CiAgICAvLyBvcC5jb25jYXQoZzFOZWcoQTEpLCBCMSksIC8vIEcxIHBvaW50cwogICAgc3dhcAogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjgwOAogICAgLy8gb3AuY29uY2F0KHZrLlhfMiwgRzJfT05FKSwgLy8gRzIgcG9pbnRzCiAgICBzd2FwCiAgICBieXRlYyA2IC8vIDB4MDI0YWEyYjJmMDhmMGE5MTI2MDgwNTI3MmRjNTEwNTFjNmU0N2FkNGZhNDAzYjAyYjQ1MTBiNjQ3YWUzZDE3NzBiYWMwMzI2YTgwNWJiZWZkNDgwNTZjOGMxMjFiZGI4MTNlMDJiNjA1MjcxOWY2MDdkYWNkM2EwODgyNzRmNjU1OTZiZDBkMDk5MjBiNjFhYjVkYTYxYmJkYzdmNTA0OTMzNGNmMTEyMTM5NDVkNTdlNWFjN2QwNTVkMDQyYjdlMGNlNWQ1Mjc3MjdkNmUxMThjYzljZGM2ZGEyZTM1MWFhZGZkOWJhYThjYmRkM2E3NmQ0MjlhNjk1MTYwZDEyYzkyM2FjOWNjM2JhY2EyODllMTkzNTQ4NjA4YjgyODAxMDYwNmM0YTAyZWE3MzRjYzMyYWNkMmIwMmJjMjhiOTljYjNlMjg3ZTg1YTc2M2FmMjY3NDkyYWI1NzJlOTlhYjNmMzcwZDI3NWNlYzFkYTFhYWE5MDc1ZmYwNWY3OWJlCiAgICBjb25jYXQKICAgIC8vIGNvbnRyYWN0cy9wbG9ua19ibHMxMjM4MS5hbGdvLnRzOjgwNS04MDkKICAgIC8vIGNvbnN0IHJlcyA9IG9wLkVsbGlwdGljQ3VydmUucGFpcmluZ0NoZWNrKAogICAgLy8gICBvcC5FYy5CTFMxMl8zODFnMSwKICAgIC8vICAgb3AuY29uY2F0KGcxTmVnKEExKSwgQjEpLCAvLyBHMSBwb2ludHMKICAgIC8vICAgb3AuY29uY2F0KHZrLlhfMiwgRzJfT05FKSwgLy8gRzIgcG9pbnRzCiAgICAvLyApOwogICAgZWNfcGFpcmluZ19jaGVjayBCTFMxMl8zODFnMQogICAgLy8gY29udHJhY3RzL3ZlcmlmaWVyLmFsZ28udHM6MTYKICAgIC8vIGFzc2VydCh2ZXJpZnlGcm9tVGVtcGxhdGUoc2lnbmFscywgcHJvb2YpLCAiVmVyaWZpY2F0aW9uIGZhaWxlZCIpOwogICAgYXNzZXJ0IC8vIFZlcmlmaWNhdGlvbiBmYWlsZWQKICAgIHJldHN1YgoKdmVyaWZ5X3Rlcm5hcnlfZmFsc2VAMTQ6CiAgICBmcmFtZV9kaWcgMzgKICAgIGZyYW1lX2J1cnkgMzYKICAgIGIgdmVyaWZ5X3Rlcm5hcnlfbWVyZ2VAMTUK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" }, "byteCode": { "approval": "CiASYCABAIADwAGgAuADwASgBYAGiAaQBpgGoAbgB+ACACYHIHPtp1MpnX1IMznYCAmh2AVTvaQC//5b/v////8AAAABAAABASBz7adTKZ19SDM52AgJodgFU72kAv/+W/7/////AAAAAADAAQJKorLwjwqRJggFJy3FEFHG5HrU+kA7ArRRC2R649F3C6wDJqgFu+/UgFbIwSG9uBPgK2BScZ9gfazToIgnT2VZa9DQmSC2GrXaYbvcf1BJM0zxEhOUXVflrH0FXQQrfgzl1SdyfW4RjMnNxtouNRqt/ZuqjL3Tp21CmmlRYNEskjrJzDusoonhk1SGCLgoAQYGxKAupzTMMqzSsCvCi5nLPih+hadjryZ0kqtXLpmrPzcNJ1zsHaGqqQdf8F95vjEbQQAzggIElcEM5ARD2Qo4NhoAjgIAEwABADEZFEQxGEQ2GgE2GgKIAF8kQzEZgQISRDEYRCRDMRlA/90xGBREJEOKAgGL/iiqi/8oqkwooEyhKKqJigEBi/8VIw5EI6+L/6tJFSMSRImKAgAhEUEABov+sIv/sImKAQGL/wIoqkkVIw5EI6+riYoCACVHISpHBCkVJUsBDyVLAk8CTSJLAg8iSwNPAk0pTwJLAlJJFSISRCEFSwMPIQVLBE8CTSlPA0sCUkkVIhJEIQZLBA8hBksFTwJNKU8DSwJSSRUiEkQhBEsFDyEESwZPAk0pTwNLAlJJFSISRCEHSwYPIQdLB08CTSlPA0sCUkkVIhJEIQhLBw8hCEsITwJNKU8DSwJSSRUiEkQhCUsIDyEJSwlPAk0pTwNLAlJJFSISRCEKSwkPIQpLCk8CTSlPA0sCUkkVIhJEIQtLCg8hC0sLTwJNKU8DSwJSFyEMSwsPIQxLDE8CTSlPA0sCUhchDUsMDyENSw1PAk0pTwNLAlIXIQ5LDQ8hDksOTwJNKU8DSwJSFyEPSw4PIQ9PD08CTSlPA08CUkkVIQUSRE8MTwxQTwtQTwpQTwlQTwhQTwdQTwZQTwUWUE8EFlBPAxZQTwIWUExQRwJXAGBLAVdgYFBLAVfAYFBLASEGIlhQSU4CSwEhBCJYSU4DUEsBIQciWElOA1BLASEIIlhJTgNQTCEJIlhJTgJQi/4lWSWLL4suDEEAIIv+VwIAiy9JTgIjCyNYKKqI/hKLLUxQjC0kCIwvQv/Yi/9XAGBJjAmLLUxQi/9XYGBJjApQi/9XwGBJjAVQiP4HSYj+A1BJjC2L/yEGIlhJjBdQiP3ySYwLi/8hBCJYSYwGUIv/IQciWEmMB1CL/yEIIlhJjAhQiP3OSYwgi/+B4AYjWEmMElCL/4GAByNYSYwTUIv/gaAHI1hJjBRQi/+BwAcjWEmMD1CL/yEPI1hJjA1Qi/+BgAgjWEmMDlAhBa9MiP2DXCCMHoECjCOLI4EGDEEALYsjSSQJIwuLHklPAiNYSwFXICCjKKpJFSMORCOvq0sCIwtMXYweJAiMI0L/y4v/IQkiWEmMHIv/IQoiWEmMGFBJjB2I/S2LLYsLUIsgUIseUExQgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUEmMEElXACCABGJldGFMiPy9SVcgIIAFZ2FtbWFMiPyuSVdAIIAFYWxwaGFMiPyfSVdgIEmMIYACeGlMiPyQSYHAAiNYgAF1TIj8g0khECNYgAN4aW5MiPx1SSEEI1iAAnpoTIj8aFeAwElXICCABHZbMV1MiPxXSVdAIIAEdlsyXUyI/ElJV2AggAR2WzNdTIj8O0lXgCCABHZbNF1MiPwtV6AggAR2WzVdTIj8ICSMIiWMI4snIQpbiyMNQQAYiyFJoyiqjCGLIoECC4wiiyMkCIwjQv/diyFJFSMORCOvSYwDSquLECEQTwJdTwIriPu1SRUjDkRPAqshBExdjBCLIhYoqowWK4wfgCIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjACLJyELW0mMJkAE/ySMJCSMJYsliyQOQQC9ixBJIQQjWIsfSU8CoyiqTwJXYCBPAoj7RYsWoyiqTCiqjAEoqkkqqUSAIHPtp1MpnX1IMznYCAmh2AVTvaQC//5b/v////7/////K4waTCiqjAyMEYsRKqVBAC2LESusKqmLGowbQQAJixqLDKMoqowbixuMGosMSaMoqowMixGAAQKijBFC/8yLAYsaoyiqSRUjDkSLA6uLAElPAlBMJVkkCBZXBgJcAIwAix8nBaMoqowfiyUkCIwlQv87gAIBoosQUIsAUEmMBEklWUsBFVJJVwIAjAJXIiBJjBWABkwxKHhpKUyI+pwqjBkljCOLI4suDEEAK4v+VwIAiyNJTgIjCyNYKKpMJAhJjCMjC4sCTCNYoyiqixlMiPpBjBlC/82LGUkVIw5EiwNJTgKrgAZQSSh4aSlLAYj6SYsEgwICoANYSVdAIElLAaMoqosVoyiqSwJXACBJiw9JTgijKKqLEklOBiiqTCiqSwGgKKpLBVcgIEwoqkwoqkxLAaAoqksDiw1JTgyjKKqLE0lOBCiqTCiqSwGgKKooqksDoCiqixRJTgooqklLBaAoqk8ETwOjKKpJTwKjKKqLDklOD6MoqksJoyiqTw1LCYj5j0yI+YtJFSMORE8Oq4ACcjBLAYj5oYsoiwZQiwdQiwhQSw1LB6MoqksNIQQjWEkoqipMiPlaSw8hECNYSUsDoyiqKkyI+UlLAU8CoyiqTwOjKKoqTIj5OE8DiPlGSxGI+UFQSwqI+TtQSw+I+TVQTwOI+S9QTwKI+SlQTIj5JFDjAkkVIhJEiyngAkkVIhJESwxXYCBLCUsBoyiqSSiqTwqgKKooqksIoCiqiydJTgMhDIEIWEsCoyiqKKpPCaAoqiiqSwmgKKpLAyENgQhYTwOjKKooqk8IoCiqKKpPCKAoqk4CoyiqoyiqSwmjKKooqk8IKKqgKKpLCoHAAiNYTCiqSwEoqqAoqosXTOECSRUiEkRPBEzgAkkVIhJETwhPCKMoqksLoyiqTwajKKqLLEzhAkkVIhJEJwThAkkVIhJE4AJJFSISRIsJiwpQiwVQiypQiytQTwhXgMBJVyAgSwFXQCBKUEsDV2AgTEsBUEsEV4AgTEsBUE8FV6AgTEsBUE8GTOMCSRUiEkRLBkzgAkkVIhJETwZMUElXAGBMV2BggAFETwKI+A6AAUZLAYj4Bk8FTwyjKKpPCYj3008FTwmjKKpMKKpMKKqgKKpPBE8IoyiqTCiqTCiqoCiqTwNPCaMoqkwoqkwoqqAoqk8CTwejKKpMKKpMKKqgKKpLAk8GoyiqTCiqTCiqoCiqgGAX8dOnMZfXlCaVY4xPqawPw2iMT5d0uQWhTjo/FxusWGxV6D/5ehrv+zrwCtsixrsIs/SB46qg8aCeMO10HYrk/PXgldXQCvYA2xjLLASz7dA8x0SiiIrkDKojKUbF5+FM4QJJFSISRIABRUsBiPc4ixhLA+ECSRUiEkSLHEzgAkkVIhJETwNLBaMoqicFoyiqiPcATwVMUIsdTOMCSRUiEkRPA+ACSRUiEkRPAicE4QJJFSISROACSRUiEkSAAkExSwKI9uKAAkIxSwGI9tlMJwThAkkVIhJEgAduZWcoQTEpSwGI9sFPAiEOIQVYgAZ2ay5YXzJLAYj2rYAGRzJfT05FJwaI9qBMTwJQTCcGUOICRImLJowkQvr9", "clear": "CoEBQw==" }, "events": [], "templateVariables": { "DEBUG_LOGGING": { "type": "AVMUint64" }, "VERIFICATION_KEY": { "type": "AVMBytes" }, "ROOT_OF_UNITY": { "type": "AVMBytes" } } };
13
+ var PlonkVerifierParamsFactory = class {
14
+ /**
15
+ * Gets available closeOut ABI call param factories
16
+ */
17
+ static get closeOut() {
18
+ return {
19
+ /**
20
+ * Constructs close out ABI call params for the PlonkVerifier smart contract using the _dummy((byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192]))void ABI method
21
+ *
22
+ * @param params Parameters for the call
23
+ * @returns An `AppClientMethodCallParams` object for the call
24
+ */
25
+ _dummy(params) {
26
+ return {
27
+ ...params,
28
+ method: "_dummy((byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192]))void",
29
+ args: Array.isArray(params.args) ? params.args : [params.args._vk]
30
+ };
31
+ }
32
+ };
33
+ }
34
+ /**
35
+ * Constructs a no op call for the verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void ABI method
36
+ *
37
+ * @param params Parameters for the call
38
+ * @returns An `AppClientMethodCallParams` object for the call
39
+ */
40
+ static verify(params) {
41
+ return {
42
+ ...params,
43
+ method: "verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void",
44
+ args: Array.isArray(params.args) ? params.args : [params.args.signals, params.args.proof]
45
+ };
46
+ }
47
+ };
48
+ var PlonkVerifierFactory = class {
49
+ /**
50
+ * The underlying `AppFactory` for when you want to have more flexibility
51
+ */
52
+ appFactory;
53
+ /**
54
+ * Creates a new instance of `PlonkVerifierFactory`
55
+ *
56
+ * @param params The parameters to initialise the app factory with
57
+ */
58
+ constructor(params) {
59
+ this.appFactory = new _AppFactory({
60
+ ...params,
61
+ appSpec: APP_SPEC
62
+ });
63
+ }
64
+ /** The name of the app (from the ARC-32 / ARC-56 app spec or override). */
65
+ get appName() {
66
+ return this.appFactory.appName;
67
+ }
68
+ /** The ARC-56 app spec being used */
69
+ get appSpec() {
70
+ return APP_SPEC;
71
+ }
72
+ /** A reference to the underlying `AlgorandClient` this app factory is using. */
73
+ get algorand() {
74
+ return this.appFactory.algorand;
75
+ }
76
+ /**
77
+ * Returns a new `AppClient` client for an app instance of the given ID.
78
+ *
79
+ * Automatically populates appName, defaultSender and source maps from the factory
80
+ * if not specified in the params.
81
+ * @param params The parameters to create the app client
82
+ * @returns The `AppClient`
83
+ */
84
+ getAppClientById(params) {
85
+ return new PlonkVerifierClient(this.appFactory.getAppClientById(params));
86
+ }
87
+ /**
88
+ * Returns a new `AppClient` client, resolving the app by creator address and name
89
+ * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note).
90
+ *
91
+ * Automatically populates appName, defaultSender and source maps from the factory
92
+ * if not specified in the params.
93
+ * @param params The parameters to create the app client
94
+ * @returns The `AppClient`
95
+ */
96
+ async getAppClientByCreatorAndName(params) {
97
+ return new PlonkVerifierClient(await this.appFactory.getAppClientByCreatorAndName(params));
98
+ }
99
+ /**
100
+ * Idempotently deploys the PlonkVerifier smart contract.
101
+ *
102
+ * @param params The arguments for the contract calls and any additional parameters for the call
103
+ * @returns The deployment result
104
+ */
105
+ async deploy(params = {}) {
106
+ const result = await this.appFactory.deploy({
107
+ ...params
108
+ });
109
+ return { result: result.result, appClient: new PlonkVerifierClient(result.appClient) };
110
+ }
111
+ /**
112
+ * Get parameters to create transactions (create and deploy related calls) for the current app. A good mental model for this is that these parameters represent a deferred transaction creation.
113
+ */
114
+ params = {
115
+ /**
116
+ * Gets available create methods
117
+ */
118
+ create: {
119
+ /**
120
+ * Creates a new instance of the PlonkVerifier smart contract using a bare call.
121
+ *
122
+ * @param params The params for the bare (raw) call
123
+ * @returns The params for a create call
124
+ */
125
+ bare: (params) => {
126
+ return this.appFactory.params.bare.create(params);
127
+ }
128
+ }
129
+ };
130
+ /**
131
+ * Create transactions for the current app
132
+ */
133
+ createTransaction = {
134
+ /**
135
+ * Gets available create methods
136
+ */
137
+ create: {
138
+ /**
139
+ * Creates a new instance of the PlonkVerifier smart contract using a bare call.
140
+ *
141
+ * @param params The params for the bare (raw) call
142
+ * @returns The transaction for a create call
143
+ */
144
+ bare: (params) => {
145
+ return this.appFactory.createTransaction.bare.create(params);
146
+ }
147
+ }
148
+ };
149
+ /**
150
+ * Send calls to the current app
151
+ */
152
+ send = {
153
+ /**
154
+ * Gets available create methods
155
+ */
156
+ create: {
157
+ /**
158
+ * Creates a new instance of the PlonkVerifier smart contract using a bare call.
159
+ *
160
+ * @param params The params for the bare (raw) call
161
+ * @returns The create result
162
+ */
163
+ bare: async (params) => {
164
+ const result = await this.appFactory.send.bare.create(params);
165
+ return { result: result.result, appClient: new PlonkVerifierClient(result.appClient) };
166
+ }
167
+ }
168
+ };
169
+ };
170
+ var PlonkVerifierClient = class _PlonkVerifierClient {
171
+ /**
172
+ * The underlying `AppClient` for when you want to have more flexibility
173
+ */
174
+ appClient;
175
+ constructor(appClientOrParams) {
176
+ this.appClient = appClientOrParams instanceof _AppClient ? appClientOrParams : new _AppClient({
177
+ ...appClientOrParams,
178
+ appSpec: APP_SPEC
179
+ });
180
+ }
181
+ /**
182
+ * Checks for decode errors on the given return value and maps the return value to the return type for the given method
183
+ * @returns The typed return value or undefined if there was no value
184
+ */
185
+ decodeReturnValue(method, returnValue) {
186
+ return returnValue !== void 0 ? getArc56ReturnValue(returnValue, this.appClient.getABIMethod(method), APP_SPEC.structs) : void 0;
187
+ }
188
+ /**
189
+ * Returns a new `PlonkVerifierClient` client, resolving the app by creator address and name
190
+ * using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note).
191
+ * @param params The parameters to create the app client
192
+ */
193
+ static async fromCreatorAndName(params) {
194
+ return new _PlonkVerifierClient(await _AppClient.fromCreatorAndName({ ...params, appSpec: APP_SPEC }));
195
+ }
196
+ /**
197
+ * Returns an `PlonkVerifierClient` instance for the current network based on
198
+ * pre-determined network-specific app IDs specified in the ARC-56 app spec.
199
+ *
200
+ * If no IDs are in the app spec or the network isn't recognised, an error is thrown.
201
+ * @param params The parameters to create the app client
202
+ */
203
+ static async fromNetwork(params) {
204
+ return new _PlonkVerifierClient(await _AppClient.fromNetwork({ ...params, appSpec: APP_SPEC }));
205
+ }
206
+ /** The ID of the app instance this client is linked to. */
207
+ get appId() {
208
+ return this.appClient.appId;
209
+ }
210
+ /** The app address of the app instance this client is linked to. */
211
+ get appAddress() {
212
+ return this.appClient.appAddress;
213
+ }
214
+ /** The name of the app. */
215
+ get appName() {
216
+ return this.appClient.appName;
217
+ }
218
+ /** The ARC-56 app spec being used */
219
+ get appSpec() {
220
+ return this.appClient.appSpec;
221
+ }
222
+ /** A reference to the underlying `AlgorandClient` this app client is using. */
223
+ get algorand() {
224
+ return this.appClient.algorand;
225
+ }
226
+ /**
227
+ * Get parameters to create transactions for the current app. A good mental model for this is that these parameters represent a deferred transaction creation.
228
+ */
229
+ params = {
230
+ /**
231
+ * Gets available closeOut methods
232
+ */
233
+ closeOut: {
234
+ /**
235
+ * Makes a close out call to an existing instance of the PlonkVerifier smart contract using the `_dummy((byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192]))void` ABI method.
236
+ *
237
+ * Dummy function that only exists so we can have the VerificationKey type in the generated client
238
+ *
239
+ * @param params The params for the smart contract call
240
+ * @returns The closeOut params
241
+ */
242
+ _dummy: (params) => {
243
+ return this.appClient.params.closeOut(PlonkVerifierParamsFactory.closeOut._dummy(params));
244
+ }
245
+ },
246
+ /**
247
+ * Makes a clear_state call to an existing instance of the PlonkVerifier smart contract.
248
+ *
249
+ * @param params The params for the bare (raw) call
250
+ * @returns The clearState result
251
+ */
252
+ clearState: (params) => {
253
+ return this.appClient.params.bare.clearState(params);
254
+ },
255
+ /**
256
+ * Makes a call to the PlonkVerifier smart contract using the `verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void` ABI method.
257
+ *
258
+ * @param params The params for the smart contract call
259
+ * @returns The call params
260
+ */
261
+ verify: (params) => {
262
+ return this.appClient.params.call(PlonkVerifierParamsFactory.verify(params));
263
+ }
264
+ };
265
+ /**
266
+ * Create transactions for the current app
267
+ */
268
+ createTransaction = {
269
+ /**
270
+ * Gets available closeOut methods
271
+ */
272
+ closeOut: {
273
+ /**
274
+ * Makes a close out call to an existing instance of the PlonkVerifier smart contract using the `_dummy((byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192]))void` ABI method.
275
+ *
276
+ * Dummy function that only exists so we can have the VerificationKey type in the generated client
277
+ *
278
+ * @param params The params for the smart contract call
279
+ * @returns The closeOut transaction
280
+ */
281
+ _dummy: (params) => {
282
+ return this.appClient.createTransaction.closeOut(PlonkVerifierParamsFactory.closeOut._dummy(params));
283
+ }
284
+ },
285
+ /**
286
+ * Makes a clear_state call to an existing instance of the PlonkVerifier smart contract.
287
+ *
288
+ * @param params The params for the bare (raw) call
289
+ * @returns The clearState result
290
+ */
291
+ clearState: (params) => {
292
+ return this.appClient.createTransaction.bare.clearState(params);
293
+ },
294
+ /**
295
+ * Makes a call to the PlonkVerifier smart contract using the `verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void` ABI method.
296
+ *
297
+ * @param params The params for the smart contract call
298
+ * @returns The call transaction
299
+ */
300
+ verify: (params) => {
301
+ return this.appClient.createTransaction.call(PlonkVerifierParamsFactory.verify(params));
302
+ }
303
+ };
304
+ /**
305
+ * Send calls to the current app
306
+ */
307
+ send = {
308
+ /**
309
+ * Gets available closeOut methods
310
+ */
311
+ closeOut: {
312
+ /**
313
+ * Makes a close out call to an existing instance of the PlonkVerifier smart contract using the `_dummy((byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint64,uint64,uint64,uint64,byte[192]))void` ABI method.
314
+ *
315
+ * Dummy function that only exists so we can have the VerificationKey type in the generated client
316
+ *
317
+ * @param params The params for the smart contract call
318
+ * @returns The closeOut result
319
+ */
320
+ _dummy: async (params) => {
321
+ const result = await this.appClient.send.closeOut(PlonkVerifierParamsFactory.closeOut._dummy(params));
322
+ return { ...result, return: result.return };
323
+ }
324
+ },
325
+ /**
326
+ * Makes a clear_state call to an existing instance of the PlonkVerifier smart contract.
327
+ *
328
+ * @param params The params for the bare (raw) call
329
+ * @returns The clearState result
330
+ */
331
+ clearState: (params) => {
332
+ return this.appClient.send.bare.clearState(params);
333
+ },
334
+ /**
335
+ * Makes a call to the PlonkVerifier smart contract using the `verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void` ABI method.
336
+ *
337
+ * @param params The params for the smart contract call
338
+ * @returns The call result
339
+ */
340
+ verify: async (params) => {
341
+ const result = await this.appClient.send.call(PlonkVerifierParamsFactory.verify(params));
342
+ return { ...result, return: result.return };
343
+ }
344
+ };
345
+ /**
346
+ * Clone this app client with different params
347
+ *
348
+ * @param params The params to use for the the cloned app client. Omit a param to keep the original value. Set a param to override the original value. Setting to undefined will clear the original value.
349
+ * @returns A new app client with the altered params
350
+ */
351
+ clone(params) {
352
+ return new _PlonkVerifierClient(this.appClient.clone(params));
353
+ }
354
+ /**
355
+ * Methods to access state for the current PlonkVerifier app
356
+ */
357
+ state = {};
358
+ newGroup() {
359
+ const client = this;
360
+ const composer = this.algorand.newGroup();
361
+ let promiseChain = Promise.resolve();
362
+ const resultMappers = [];
363
+ return {
364
+ /**
365
+ * Add a verify(uint256[],(byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],byte[96],uint256,uint256,uint256,uint256,uint256,uint256))void method call against the PlonkVerifier contract
366
+ */
367
+ verify(params) {
368
+ promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.verify(params)));
369
+ resultMappers.push(void 0);
370
+ return this;
371
+ },
372
+ get closeOut() {
373
+ return {
374
+ _dummy: (params) => {
375
+ promiseChain = promiseChain.then(async () => composer.addAppCallMethodCall(await client.params.closeOut._dummy(params)));
376
+ resultMappers.push(void 0);
377
+ return this;
378
+ }
379
+ };
380
+ },
381
+ /**
382
+ * Add a clear state call to the PlonkVerifier contract
383
+ */
384
+ clearState(params) {
385
+ promiseChain = promiseChain.then(() => composer.addAppCall(client.params.clearState(params)));
386
+ return this;
387
+ },
388
+ addTransaction(txn, signer) {
389
+ promiseChain = promiseChain.then(() => composer.addTransaction(txn, signer));
390
+ return this;
391
+ },
392
+ async composer() {
393
+ await promiseChain;
394
+ return composer;
395
+ },
396
+ async simulate(options) {
397
+ await promiseChain;
398
+ const result = await (!options ? composer.simulate() : composer.simulate(options));
399
+ return {
400
+ ...result,
401
+ returns: result.returns?.map((val, i) => resultMappers[i] !== void 0 ? resultMappers[i](val) : val.returnValue)
402
+ };
403
+ },
404
+ async send(params) {
405
+ await promiseChain;
406
+ const result = await composer.send(params);
407
+ return {
408
+ ...result,
409
+ returns: result.returns?.map((val, i) => resultMappers[i] !== void 0 ? resultMappers[i](val) : val.returnValue)
410
+ };
411
+ }
412
+ };
413
+ }
414
+ };
415
+
416
+ // src/index.ts
417
+ import * as snarkjs from "snarkjs";
418
+ import {
419
+ getABIEncodedValue
420
+ } from "@algorandfoundation/algokit-utils/types/app-arc56";
421
+ import { readFileSync } from "fs";
422
+ import "algosdk";
423
+ function stringValuesToBigints(obj) {
424
+ for (const key in obj) {
425
+ if (typeof obj[key] === "string" && /^\d+$/.test(obj[key])) {
426
+ obj[key] = BigInt(obj[key]);
427
+ } else if (typeof obj[key] === "object" && obj[key] !== null) {
428
+ stringValuesToBigints(obj[key]);
429
+ }
430
+ }
431
+ }
432
+ async function getVkey(zKey2, curve) {
433
+ const vkey = await snarkjs.zKey.exportVerificationKey(zKey2, console);
434
+ ["Ql", "Qr", "Qo", "Qm", "Qc", "S1", "S2", "S3"].forEach((p) => {
435
+ stringValuesToBigints(vkey[p]);
436
+ const point = curve.G1.fromObject(vkey[p]);
437
+ vkey[`${p}Bytes`] = curve.G1.toUncompressed(point);
438
+ });
439
+ stringValuesToBigints(vkey.X_2);
440
+ const x2Point = curve.G2.fromObject(vkey.X_2);
441
+ const x2Uncompressed = curve.G2.toUncompressed(x2Point);
442
+ const x1 = x2Uncompressed.subarray(0, 48);
443
+ const x0 = x2Uncompressed.subarray(48, 96);
444
+ const y1 = x2Uncompressed.subarray(96, 144);
445
+ const y0 = x2Uncompressed.subarray(144, 192);
446
+ const x2Bytes = new Uint8Array(192);
447
+ x2Bytes.set(x0, 0);
448
+ x2Bytes.set(x1, 48);
449
+ x2Bytes.set(y0, 96);
450
+ x2Bytes.set(y1, 144);
451
+ return {
452
+ power: vkey.power,
453
+ nPublic: vkey.nPublic,
454
+ ql: vkey.QlBytes,
455
+ qr: vkey.QrBytes,
456
+ qo: vkey.QoBytes,
457
+ qm: vkey.QmBytes,
458
+ qc: vkey.QcBytes,
459
+ s1: vkey.S1Bytes,
460
+ s2: vkey.S2Bytes,
461
+ s3: vkey.S3Bytes,
462
+ k1: BigInt(vkey.k1),
463
+ k2: BigInt(vkey.k2),
464
+ x_2: x2Bytes
465
+ };
466
+ }
467
+ function encodeVk(vkey, appSpec) {
468
+ return getABIEncodedValue(vkey, "VerificationKey", appSpec.structs);
469
+ }
470
+ async function getProof(path, curve) {
471
+ const proof = JSON.parse(readFileSync(path, "utf8"));
472
+ return encodeProof(proof, curve);
473
+ }
474
+ function encodeProof(proof, curve) {
475
+ ["A", "B", "C", "Z", "T1", "T2", "T3", "Wxi", "Wxiw"].forEach((p) => {
476
+ stringValuesToBigints(proof[p]);
477
+ const point = curve.G1.fromObject(proof[p]);
478
+ proof[`${p}Bytes`] = curve.G1.toUncompressed(point);
479
+ });
480
+ ["eval_a", "eval_b", "eval_c", "eval_s1", "eval_s2", "eval_zw"].forEach(
481
+ (p) => {
482
+ proof[`${p}BigInt`] = BigInt(proof[p]);
483
+ }
484
+ );
485
+ return {
486
+ a: proof.ABytes,
487
+ b: proof.BBytes,
488
+ c: proof.CBytes,
489
+ z: proof.ZBytes,
490
+ t1: proof.T1Bytes,
491
+ t2: proof.T2Bytes,
492
+ t3: proof.T3Bytes,
493
+ wxi: proof.WxiBytes,
494
+ wxiw: proof.WxiwBytes,
495
+ evalA: proof.eval_aBigInt,
496
+ evalB: proof.eval_bBigInt,
497
+ evalC: proof.eval_cBigInt,
498
+ evalS1: proof.eval_s1BigInt,
499
+ evalS2: proof.eval_s2BigInt,
500
+ evalZw: proof.eval_zwBigInt
501
+ };
502
+ }
503
+ function encodeSignals(...inputs) {
504
+ return inputs.map((input) => {
505
+ return BigInt(input);
506
+ });
507
+ }
508
+ var AppVerifier = class {
509
+ constructor(algorand, zKey2, wasmProver) {
510
+ this.algorand = algorand;
511
+ this.zKey = zKey2;
512
+ this.wasmProver = wasmProver;
513
+ }
514
+ appClient;
515
+ curve;
516
+ async ensureCurveInstanttiation() {
517
+ if (!this.curve) {
518
+ this.curve = await snarkjs.curves.getCurveFromName("bls12381");
519
+ }
520
+ }
521
+ async deploy(params) {
522
+ if (this.appClient) {
523
+ throw new Error("AppVerifier already deployed");
524
+ }
525
+ const curve = await snarkjs.curves.getCurveFromName("bls12381");
526
+ const factory = new PlonkVerifierFactory({
527
+ algorand: this.algorand,
528
+ defaultSender: params.defaultSender
529
+ });
530
+ const vk = await getVkey(this.zKey, curve);
531
+ const vkBytes = encodeVk(vk, factory.appSpec);
532
+ const rootOfUnity = Buffer.from(
533
+ curve.Fr.toObject(curve.Fr.w[Number(vk.power)]).toString(16).padStart(64, "0"),
534
+ "hex"
535
+ );
536
+ const { appClient } = await factory.deploy({
537
+ ...params,
538
+ deployTimeParams: {
539
+ VERIFICATION_KEY: vkBytes,
540
+ ROOT_OF_UNITY: rootOfUnity,
541
+ DEBUG_LOGGING: params.debugLogging ? 1 : 0
542
+ }
543
+ });
544
+ this.appClient = appClient;
545
+ return appClient;
546
+ }
547
+ async proofAndSignals(inputs) {
548
+ await this.ensureCurveInstanttiation();
549
+ const { proof: rawProof, publicSignals: rawSignals } = await snarkjs.plonk.fullProve(inputs, this.wasmProver, this.zKey);
550
+ const proof = encodeProof(rawProof, this.curve);
551
+ const signals = encodeSignals(...rawSignals);
552
+ return { proof, signals };
553
+ }
554
+ assertDeployed() {
555
+ if (!this.appClient) {
556
+ throw new Error("AppVerifier not deployed");
557
+ }
558
+ }
559
+ // Methods that take in proof and signals directly
560
+ async simulateVerificationWithProofAndSignals(proofAndSignals, simParams) {
561
+ this.assertDeployed();
562
+ return this.appClient.newGroup().verify({ args: proofAndSignals }).simulate(simParams ?? {});
563
+ }
564
+ async verifyTransactionFromProofAndSignals(proofAndSignals) {
565
+ this.assertDeployed();
566
+ return (await this.appClient.createTransaction.verify({
567
+ args: proofAndSignals
568
+ })).transactions[0];
569
+ }
570
+ async callVerifyFromProofAndSignals(proofAndSignals, callParams) {
571
+ this.assertDeployed();
572
+ return this.appClient.send.verify({ ...callParams, args: proofAndSignals });
573
+ }
574
+ // Methods that generate proof and signals internally
575
+ async simulateVerification(inputs, simParams) {
576
+ return this.simulateVerificationWithProofAndSignals(
577
+ await this.proofAndSignals(inputs),
578
+ simParams
579
+ );
580
+ }
581
+ async verifyTransaction(inputs) {
582
+ return this.verifyTransactionFromProofAndSignals(
583
+ await this.proofAndSignals(inputs)
584
+ );
585
+ }
586
+ async callVerify(inputs, callParams) {
587
+ return this.callVerifyFromProofAndSignals(
588
+ await this.proofAndSignals(inputs),
589
+ callParams
590
+ );
591
+ }
592
+ };
593
+ export {
594
+ AppVerifier,
595
+ PlonkVerifierClient,
596
+ encodeProof,
597
+ encodeSignals,
598
+ encodeVk,
599
+ getProof,
600
+ getVkey
601
+ };