Contracts

Get Contract ABI for Verified contract source code

Returns the contract ABI for the verified contract source code.

GET https://testnetapi.metadium.com/v1/contracts/{contract_hash}/abi
api-key: Your API Key

Query Parameters

Parameter

Description

contract_hash

type: String

value: Address of contract

required: true


Get Contract Source Code for Verified Contract Source Code

Returns the contract source code for the verified contract source code.

GET https://explorerapi.test.wemix.com/v1/contracts/0x9afffe2525f25515c127c42ca18dacc5b331995a/code
api-key: Your API Key

Query Parameters

Parameter

Description

contract_hash

type: String

value: Address of contract

required: true


Verify Contract Source Code

Returns verification results for contract source code.

POST https://testnetapi.metadium.com/v1/contracts/{contract_hash}/verify
api-key: Your API Key
Content-Type: application/json

{
    "contract_name": "TestNFT",
    "compiler": "0.6.2",
    "runs_optimizer": 200,
    "optimization_enabled": 1,
    "contract_source": "Ly8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy91dGlscy9Db250ZXh0LnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOC4wOwoKLyoKICogQGRldiBQcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCBleGVjdXRpb24gY29udGV4dCwgaW5jbHVkaW5nIHRoZQogKiBzZW5kZXIgb2YgdGhlIHRyYW5zYWN0aW9uIGFuZCBpdHMgZGF0YS4gV2hpbGUgdGhlc2UgYXJlIGdlbmVyYWxseSBhdmFpbGFibGUKICogdmlhIG1zZy5zZW5kZXIgYW5kIG1zZy5kYXRhLCB0aGV5IHNob3VsZCBub3QgYmUgYWNjZXNzZWQgaW4gc3VjaCBhIGRpcmVjdAogKiBtYW5uZXIsIHNpbmNlIHdoZW4gZGVhbGluZyB3aXRoIEdTTiBtZXRhLXRyYW5zYWN0aW9ucyB0aGUgYWNjb3VudCBzZW5kaW5nIGFuZAogKiBwYXlpbmcgZm9yIGV4ZWN1dGlvbiBtYXkgbm90IGJlIHRoZSBhY3R1YWwgc2VuZGVyIChhcyBmYXIgYXMgYW4gYXBwbGljYXRpb24KICogaXMgY29uY2VybmVkKS4KICoKICogVGhpcyBjb250cmFjdCBpcyBvbmx5IHJlcXVpcmVkIGZvciBpbnRlcm1lZGlhdGUsIGxpYnJhcnktbGlrZSBjb250cmFjdHMuCiAqLwphYnN0cmFjdCBjb250cmFjdCBDb250ZXh0IHsKICAgIGZ1bmN0aW9uIF9tc2dTZW5kZXIoKSBpbnRlcm5hbCB2aWV3IHZpcnR1YWwgcmV0dXJucyAoYWRkcmVzcyBwYXlhYmxlKSB7CiAgICAgICAgcmV0dXJuIG1zZy5zZW5kZXI7CiAgICB9CgogICAgZnVuY3Rpb24gX21zZ0RhdGEoKSBpbnRlcm5hbCB2aWV3IHZpcnR1YWwgcmV0dXJucyAoYnl0ZXMgbWVtb3J5KSB7CiAgICAgICAgdGhpczsgLy8gc2lsZW5jZSBzdGF0ZSBtdXRhYmlsaXR5IHdhcm5pbmcgd2l0aG91dCBnZW5lcmF0aW5nIGJ5dGVjb2RlIC0gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ldGhlcmV1bS9zb2xpZGl0eS9pc3N1ZXMvMjY5MQogICAgICAgIHJldHVybiBtc2cuZGF0YTsKICAgIH0KfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy9pbnRyb3NwZWN0aW9uL0lFUkMxNjUuc29sCgovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCgpwcmFnbWEgc29saWRpdHkgPj0wLjYuMCA8MC44LjA7CgovKioKICogQGRldiBJbnRlcmZhY2Ugb2YgdGhlIEVSQzE2NSBzdGFuZGFyZCwgYXMgZGVmaW5lZCBpbiB0aGUKICogaHR0cHM6Ly9laXBzLmV0aGVyZXVtLm9yZy9FSVBTL2VpcC0xNjVbRUlQXS4KICoKICogSW1wbGVtZW50ZXJzIGNhbiBkZWNsYXJlIHN1cHBvcnQgb2YgY29udHJhY3QgaW50ZXJmYWNlcywgd2hpY2ggY2FuIHRoZW4gYmUKICogcXVlcmllZCBieSBvdGhlcnMgKHtFUkMxNjVDaGVja2VyfSkuCiAqCiAqIEZvciBhbiBpbXBsZW1lbnRhdGlvbiwgc2VlIHtFUkMxNjV9LgogKi8KaW50ZXJmYWNlIElFUkMxNjUgewogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbnRyYWN0IGltcGxlbWVudHMgdGhlIGludGVyZmFjZSBkZWZpbmVkIGJ5CiAgICAgKiBgaW50ZXJmYWNlSWRgLiBTZWUgdGhlIGNvcnJlc3BvbmRpbmcKICAgICAqIGh0dHBzOi8vZWlwcy5ldGhlcmV1bS5vcmcvRUlQUy9laXAtMTY1I2hvdy1pbnRlcmZhY2VzLWFyZS1pZGVudGlmaWVkW0VJUCBzZWN0aW9uXQogICAgICogdG8gbGVhcm4gbW9yZSBhYm91dCBob3cgdGhlc2UgaWRzIGFyZSBjcmVhdGVkLgogICAgICoKICAgICAqIFRoaXMgZnVuY3Rpb24gY2FsbCBtdXN0IHVzZSBsZXNzIHRoYW4gMzAgMDAwIGdhcy4KICAgICAqLwogICAgZnVuY3Rpb24gc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0IGludGVyZmFjZUlkKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpOwp9CgovLyBGaWxlOiBvcGVuemVwcGVsaW4tc29saWRpdHkvY29udHJhY3RzL3Rva2VuL0VSQzcyMS9JRVJDNzIxLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOC4wOwoKCi8qKgogKiBAZGV2IFJlcXVpcmVkIGludGVyZmFjZSBvZiBhbiBFUkM3MjEgY29tcGxpYW50IGNvbnRyYWN0LgogKi8KaW50ZXJmYWNlIElFUkM3MjEgaXMgSUVSQzE2NSB7CiAgICAvKioKICAgICAqIEBkZXYgRW1pdHRlZCB3aGVuIGB0b2tlbklkYCB0b2tlbiBpcyB0cmFuc2ZlcnJlZCBmcm9tIGBmcm9tYCB0byBgdG9gLgogICAgICovCiAgICBldmVudCBUcmFuc2ZlcihhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IGluZGV4ZWQgdG9rZW5JZCk7CgogICAgLyoqCiAgICAgKiBAZGV2IEVtaXR0ZWQgd2hlbiBgb3duZXJgIGVuYWJsZXMgYGFwcHJvdmVkYCB0byBtYW5hZ2UgdGhlIGB0b2tlbklkYCB0b2tlbi4KICAgICAqLwogICAgZXZlbnQgQXBwcm92YWwoYWRkcmVzcyBpbmRleGVkIG93bmVyLCBhZGRyZXNzIGluZGV4ZWQgYXBwcm92ZWQsIHVpbnQyNTYgaW5kZXhlZCB0b2tlbklkKTsKCiAgICAvKioKICAgICAqIEBkZXYgRW1pdHRlZCB3aGVuIGBvd25lcmAgZW5hYmxlcyBvciBkaXNhYmxlcyAoYGFwcHJvdmVkYCkgYG9wZXJhdG9yYCB0byBtYW5hZ2UgYWxsIG9mIGl0cyBhc3NldHMuCiAgICAgKi8KICAgIGV2ZW50IEFwcHJvdmFsRm9yQWxsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIG9wZXJhdG9yLCBib29sIGFwcHJvdmVkKTsKCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRva2VucyBpbiBgYG93bmVyYGAncyBhY2NvdW50LgogICAgICovCiAgICBmdW5jdGlvbiBiYWxhbmNlT2YoYWRkcmVzcyBvd25lcikgZXh0ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2IGJhbGFuY2UpOwoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBvd25lciBvZiB0aGUgYHRva2VuSWRgIHRva2VuLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIGB0b2tlbklkYCBtdXN0IGV4aXN0LgogICAgICovCiAgICBmdW5jdGlvbiBvd25lck9mKHVpbnQyNTYgdG9rZW5JZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChhZGRyZXNzIG93bmVyKTsKCiAgICAvKioKICAgICAqIEBkZXYgU2FmZWx5IHRyYW5zZmVycyBgdG9rZW5JZGAgdG9rZW4gZnJvbSBgZnJvbWAgdG8gYHRvYCwgY2hlY2tpbmcgZmlyc3QgdGhhdCBjb250cmFjdCByZWNpcGllbnRzCiAgICAgKiBhcmUgYXdhcmUgb2YgdGhlIEVSQzcyMSBwcm90b2NvbCB0byBwcmV2ZW50IHRva2VucyBmcm9tIGJlaW5nIGZvcmV2ZXIgbG9ja2VkLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIGBmcm9tYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqIC0gYHRvYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqIC0gYHRva2VuSWRgIHRva2VuIG11c3QgZXhpc3QgYW5kIGJlIG93bmVkIGJ5IGBmcm9tYC4KICAgICAqIC0gSWYgdGhlIGNhbGxlciBpcyBub3QgYGZyb21gLCBpdCBtdXN0IGJlIGhhdmUgYmVlbiBhbGxvd2VkIHRvIG1vdmUgdGhpcyB0b2tlbiBieSBlaXRoZXIge2FwcHJvdmV9IG9yIHtzZXRBcHByb3ZhbEZvckFsbH0uCiAgICAgKiAtIElmIGB0b2AgcmVmZXJzIHRvIGEgc21hcnQgY29udHJhY3QsIGl0IG11c3QgaW1wbGVtZW50IHtJRVJDNzIxUmVjZWl2ZXItb25FUkM3MjFSZWNlaXZlZH0sIHdoaWNoIGlzIGNhbGxlZCB1cG9uIGEgc2FmZSB0cmFuc2Zlci4KICAgICAqCiAgICAgKiBFbWl0cyBhIHtUcmFuc2Zlcn0gZXZlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNhZmVUcmFuc2ZlckZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIGV4dGVybmFsOwoKICAgIC8qKgogICAgICogQGRldiBUcmFuc2ZlcnMgYHRva2VuSWRgIHRva2VuIGZyb20gYGZyb21gIHRvIGB0b2AuCiAgICAgKgogICAgICogV0FSTklORzogVXNhZ2Ugb2YgdGhpcyBtZXRob2QgaXMgZGlzY291cmFnZWQsIHVzZSB7c2FmZVRyYW5zZmVyRnJvbX0gd2hlbmV2ZXIgcG9zc2libGUuCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gYGZyb21gIGNhbm5vdCBiZSB0aGUgemVybyBhZGRyZXNzLgogICAgICogLSBgdG9gIGNhbm5vdCBiZSB0aGUgemVybyBhZGRyZXNzLgogICAgICogLSBgdG9rZW5JZGAgdG9rZW4gbXVzdCBiZSBvd25lZCBieSBgZnJvbWAuCiAgICAgKiAtIElmIHRoZSBjYWxsZXIgaXMgbm90IGBmcm9tYCwgaXQgbXVzdCBiZSBhcHByb3ZlZCB0byBtb3ZlIHRoaXMgdG9rZW4gYnkgZWl0aGVyIHthcHByb3ZlfSBvciB7c2V0QXBwcm92YWxGb3JBbGx9LgogICAgICoKICAgICAqIEVtaXRzIGEge1RyYW5zZmVyfSBldmVudC4KICAgICAqLwogICAgZnVuY3Rpb24gdHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkKSBleHRlcm5hbDsKCiAgICAvKioKICAgICAqIEBkZXYgR2l2ZXMgcGVybWlzc2lvbiB0byBgdG9gIHRvIHRyYW5zZmVyIGB0b2tlbklkYCB0b2tlbiB0byBhbm90aGVyIGFjY291bnQuCiAgICAgKiBUaGUgYXBwcm92YWwgaXMgY2xlYXJlZCB3aGVuIHRoZSB0b2tlbiBpcyB0cmFuc2ZlcnJlZC4KICAgICAqCiAgICAgKiBPbmx5IGEgc2luZ2xlIGFjY291bnQgY2FuIGJlIGFwcHJvdmVkIGF0IGEgdGltZSwgc28gYXBwcm92aW5nIHRoZSB6ZXJvIGFkZHJlc3MgY2xlYXJzIHByZXZpb3VzIGFwcHJvdmFscy4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBUaGUgY2FsbGVyIG11c3Qgb3duIHRoZSB0b2tlbiBvciBiZSBhbiBhcHByb3ZlZCBvcGVyYXRvci4KICAgICAqIC0gYHRva2VuSWRgIG11c3QgZXhpc3QuCiAgICAgKgogICAgICogRW1pdHMgYW4ge0FwcHJvdmFsfSBldmVudC4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIGV4dGVybmFsOwoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBhY2NvdW50IGFwcHJvdmVkIGZvciBgdG9rZW5JZGAgdG9rZW4uCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gYHRva2VuSWRgIG11c3QgZXhpc3QuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGdldEFwcHJvdmVkKHVpbnQyNTYgdG9rZW5JZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChhZGRyZXNzIG9wZXJhdG9yKTsKCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBvciByZW1vdmUgYG9wZXJhdG9yYCBhcyBhbiBvcGVyYXRvciBmb3IgdGhlIGNhbGxlci4KICAgICAqIE9wZXJhdG9ycyBjYW4gY2FsbCB7dHJhbnNmZXJGcm9tfSBvciB7c2FmZVRyYW5zZmVyRnJvbX0gZm9yIGFueSB0b2tlbiBvd25lZCBieSB0aGUgY2FsbGVyLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIFRoZSBgb3BlcmF0b3JgIGNhbm5vdCBiZSB0aGUgY2FsbGVyLgogICAgICoKICAgICAqIEVtaXRzIGFuIHtBcHByb3ZhbEZvckFsbH0gZXZlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNldEFwcHJvdmFsRm9yQWxsKGFkZHJlc3Mgb3BlcmF0b3IsIGJvb2wgX2FwcHJvdmVkKSBleHRlcm5hbDsKCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyBpZiB0aGUgYG9wZXJhdG9yYCBpcyBhbGxvd2VkIHRvIG1hbmFnZSBhbGwgb2YgdGhlIGFzc2V0cyBvZiBgb3duZXJgLgogICAgICoKICAgICAqIFNlZSB7c2V0QXBwcm92YWxGb3JBbGx9CiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQXBwcm92ZWRGb3JBbGwoYWRkcmVzcyBvd25lciwgYWRkcmVzcyBvcGVyYXRvcikgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChib29sKTsKCiAgICAvKioKICAgICAgKiBAZGV2IFNhZmVseSB0cmFuc2ZlcnMgYHRva2VuSWRgIHRva2VuIGZyb20gYGZyb21gIHRvIGB0b2AuCiAgICAgICoKICAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgICoKICAgICAgKiAtIGBmcm9tYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAgKiAtIGB0b2AgY2Fubm90IGJlIHRoZSB6ZXJvIGFkZHJlc3MuCiAgICAgICogLSBgdG9rZW5JZGAgdG9rZW4gbXVzdCBleGlzdCBhbmQgYmUgb3duZWQgYnkgYGZyb21gLgogICAgICAqIC0gSWYgdGhlIGNhbGxlciBpcyBub3QgYGZyb21gLCBpdCBtdXN0IGJlIGFwcHJvdmVkIHRvIG1vdmUgdGhpcyB0b2tlbiBieSBlaXRoZXIge2FwcHJvdmV9IG9yIHtzZXRBcHByb3ZhbEZvckFsbH0uCiAgICAgICogLSBJZiBgdG9gIHJlZmVycyB0byBhIHNtYXJ0IGNvbnRyYWN0LCBpdCBtdXN0IGltcGxlbWVudCB7SUVSQzcyMVJlY2VpdmVyLW9uRVJDNzIxUmVjZWl2ZWR9LCB3aGljaCBpcyBjYWxsZWQgdXBvbiBhIHNhZmUgdHJhbnNmZXIuCiAgICAgICoKICAgICAgKiBFbWl0cyBhIHtUcmFuc2Zlcn0gZXZlbnQuCiAgICAgICovCiAgICBmdW5jdGlvbiBzYWZlVHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkLCBieXRlcyBjYWxsZGF0YSBkYXRhKSBleHRlcm5hbDsKfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy90b2tlbi9FUkM3MjEvSUVSQzcyMU1ldGFkYXRhLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOC4wOwoKCi8qKgogKiBAdGl0bGUgRVJDLTcyMSBOb24tRnVuZ2libGUgVG9rZW4gU3RhbmRhcmQsIG9wdGlvbmFsIG1ldGFkYXRhIGV4dGVuc2lvbgogKiBAZGV2IFNlZSBodHRwczovL2VpcHMuZXRoZXJldW0ub3JnL0VJUFMvZWlwLTcyMQogKi8KaW50ZXJmYWNlIElFUkM3MjFNZXRhZGF0YSBpcyBJRVJDNzIxIHsKCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgdG9rZW4gY29sbGVjdGlvbiBuYW1lLgogICAgICovCiAgICBmdW5jdGlvbiBuYW1lKCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KTsKCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgdG9rZW4gY29sbGVjdGlvbiBzeW1ib2wuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN5bWJvbCgpIGV4dGVybmFsIHZpZXcgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSk7CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIFVuaWZvcm0gUmVzb3VyY2UgSWRlbnRpZmllciAoVVJJKSBmb3IgYHRva2VuSWRgIHRva2VuLgogICAgICovCiAgICBmdW5jdGlvbiB0b2tlblVSSSh1aW50MjU2IHRva2VuSWQpIGV4dGVybmFsIHZpZXcgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSk7Cn0KCi8vIEZpbGU6IG9wZW56ZXBwZWxpbi1zb2xpZGl0eS9jb250cmFjdHMvdG9rZW4vRVJDNzIxL0lFUkM3MjFFbnVtZXJhYmxlLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOC4wOwoKCi8qKgogKiBAdGl0bGUgRVJDLTcyMSBOb24tRnVuZ2libGUgVG9rZW4gU3RhbmRhcmQsIG9wdGlvbmFsIGVudW1lcmF0aW9uIGV4dGVuc2lvbgogKiBAZGV2IFNlZSBodHRwczovL2VpcHMuZXRoZXJldW0ub3JnL0VJUFMvZWlwLTcyMQogKi8KaW50ZXJmYWNlIElFUkM3MjFFbnVtZXJhYmxlIGlzIElFUkM3MjEgewoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSB0b3RhbCBhbW91bnQgb2YgdG9rZW5zIHN0b3JlZCBieSB0aGUgY29udHJhY3QuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRvdGFsU3VwcGx5KCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyBhIHRva2VuIElEIG93bmVkIGJ5IGBvd25lcmAgYXQgYSBnaXZlbiBgaW5kZXhgIG9mIGl0cyB0b2tlbiBsaXN0LgogICAgICogVXNlIGFsb25nIHdpdGgge2JhbGFuY2VPZn0gdG8gZW51bWVyYXRlIGFsbCBvZiBgYG93bmVyYGAncyB0b2tlbnMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRva2VuT2ZPd25lckJ5SW5kZXgoYWRkcmVzcyBvd25lciwgdWludDI1NiBpbmRleCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2IHRva2VuSWQpOwoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIGEgdG9rZW4gSUQgYXQgYSBnaXZlbiBgaW5kZXhgIG9mIGFsbCB0aGUgdG9rZW5zIHN0b3JlZCBieSB0aGUgY29udHJhY3QuCiAgICAgKiBVc2UgYWxvbmcgd2l0aCB7dG90YWxTdXBwbHl9IHRvIGVudW1lcmF0ZSBhbGwgdG9rZW5zLgogICAgICovCiAgICBmdW5jdGlvbiB0b2tlbkJ5SW5kZXgodWludDI1NiBpbmRleCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2KTsKfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy90b2tlbi9FUkM3MjEvSUVSQzcyMVJlY2VpdmVyLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOC4wOwoKLyoqCiAqIEB0aXRsZSBFUkM3MjEgdG9rZW4gcmVjZWl2ZXIgaW50ZXJmYWNlCiAqIEBkZXYgSW50ZXJmYWNlIGZvciBhbnkgY29udHJhY3QgdGhhdCB3YW50cyB0byBzdXBwb3J0IHNhZmVUcmFuc2ZlcnMKICogZnJvbSBFUkM3MjEgYXNzZXQgY29udHJhY3RzLgogKi8KaW50ZXJmYWNlIElFUkM3MjFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBkZXYgV2hlbmV2ZXIgYW4ge0lFUkM3MjF9IGB0b2tlbklkYCB0b2tlbiBpcyB0cmFuc2ZlcnJlZCB0byB0aGlzIGNvbnRyYWN0IHZpYSB7SUVSQzcyMS1zYWZlVHJhbnNmZXJGcm9tfQogICAgICogYnkgYG9wZXJhdG9yYCBmcm9tIGBmcm9tYCwgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQuCiAgICAgKgogICAgICogSXQgbXVzdCByZXR1cm4gaXRzIFNvbGlkaXR5IHNlbGVjdG9yIHRvIGNvbmZpcm0gdGhlIHRva2VuIHRyYW5zZmVyLgogICAgICogSWYgYW55IG90aGVyIHZhbHVlIGlzIHJldHVybmVkIG9yIHRoZSBpbnRlcmZhY2UgaXMgbm90IGltcGxlbWVudGVkIGJ5IHRoZSByZWNpcGllbnQsIHRoZSB0cmFuc2ZlciB3aWxsIGJlIHJldmVydGVkLgogICAgICoKICAgICAqIFRoZSBzZWxlY3RvciBjYW4gYmUgb2J0YWluZWQgaW4gU29saWRpdHkgd2l0aCBgSUVSQzcyMS5vbkVSQzcyMVJlY2VpdmVkLnNlbGVjdG9yYC4KICAgICAqLwogICAgZnVuY3Rpb24gb25FUkM3MjFSZWNlaXZlZChhZGRyZXNzIG9wZXJhdG9yLCBhZGRyZXNzIGZyb20sIHVpbnQyNTYgdG9rZW5JZCwgYnl0ZXMgY2FsbGRhdGEgZGF0YSkgZXh0ZXJuYWwgcmV0dXJucyAoYnl0ZXM0KTsKfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy9pbnRyb3NwZWN0aW9uL0VSQzE2NS5zb2wKCi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKCnByYWdtYSBzb2xpZGl0eSA+PTAuNi4wIDwwLjguMDsKCgovKioKICogQGRldiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUge0lFUkMxNjV9IGludGVyZmFjZS4KICoKICogQ29udHJhY3RzIG1heSBpbmhlcml0IGZyb20gdGhpcyBhbmQgY2FsbCB7X3JlZ2lzdGVySW50ZXJmYWNlfSB0byBkZWNsYXJlCiAqIHRoZWlyIHN1cHBvcnQgb2YgYW4gaW50ZXJmYWNlLgogKi8KYWJzdHJhY3QgY29udHJhY3QgRVJDMTY1IGlzIElFUkMxNjUgewogICAgLyoKICAgICAqIGJ5dGVzNChrZWNjYWsyNTYoJ3N1cHBvcnRzSW50ZXJmYWNlKGJ5dGVzNCknKSkgPT0gMHgwMWZmYzlhNwogICAgICovCiAgICBieXRlczQgcHJpdmF0ZSBjb25zdGFudCBfSU5URVJGQUNFX0lEX0VSQzE2NSA9IDB4MDFmZmM5YTc7CgogICAgLyoqCiAgICAgKiBAZGV2IE1hcHBpbmcgb2YgaW50ZXJmYWNlIGlkcyB0byB3aGV0aGVyIG9yIG5vdCBpdCdzIHN1cHBvcnRlZC4KICAgICAqLwogICAgbWFwcGluZyhieXRlczQgPT4gYm9vbCkgcHJpdmF0ZSBfc3VwcG9ydGVkSW50ZXJmYWNlczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgLy8gRGVyaXZlZCBjb250cmFjdHMgbmVlZCBvbmx5IHJlZ2lzdGVyIHN1cHBvcnQgZm9yIHRoZWlyIG93biBpbnRlcmZhY2VzLAogICAgICAgIC8vIHdlIHJlZ2lzdGVyIHN1cHBvcnQgZm9yIEVSQzE2NSBpdHNlbGYgaGVyZQogICAgICAgIF9yZWdpc3RlckludGVyZmFjZShfSU5URVJGQUNFX0lEX0VSQzE2NSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzE2NS1zdXBwb3J0c0ludGVyZmFjZX0uCiAgICAgKgogICAgICogVGltZSBjb21wbGV4aXR5IE8oMSksIGd1YXJhbnRlZWQgdG8gYWx3YXlzIHVzZSBsZXNzIHRoYW4gMzAgMDAwIGdhcy4KICAgICAqLwogICAgZnVuY3Rpb24gc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0IGludGVyZmFjZUlkKSBwdWJsaWMgdmlldyB2aXJ0dWFsIG92ZXJyaWRlIHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX3N1cHBvcnRlZEludGVyZmFjZXNbaW50ZXJmYWNlSWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZWdpc3RlcnMgdGhlIGNvbnRyYWN0IGFzIGFuIGltcGxlbWVudGVyIG9mIHRoZSBpbnRlcmZhY2UgZGVmaW5lZCBieQogICAgICogYGludGVyZmFjZUlkYC4gU3VwcG9ydCBvZiB0aGUgYWN0dWFsIEVSQzE2NSBpbnRlcmZhY2UgaXMgYXV0b21hdGljIGFuZAogICAgICogcmVnaXN0ZXJpbmcgaXRzIGludGVyZmFjZSBpZCBpcyBub3QgcmVxdWlyZWQuCiAgICAgKgogICAgICogU2VlIHtJRVJDMTY1LXN1cHBvcnRzSW50ZXJmYWNlfS4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBgaW50ZXJmYWNlSWRgIGNhbm5vdCBiZSB0aGUgRVJDMTY1IGludmFsaWQgaW50ZXJmYWNlIChgMHhmZmZmZmZmZmApLgogICAgICovCiAgICBmdW5jdGlvbiBfcmVnaXN0ZXJJbnRlcmZhY2UoYnl0ZXM0IGludGVyZmFjZUlkKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICByZXF1aXJlKGludGVyZmFjZUlkICE9IDB4ZmZmZmZmZmYsICJFUkMxNjU6IGludmFsaWQgaW50ZXJmYWNlIGlkIik7CiAgICAgICAgX3N1cHBvcnRlZEludGVyZmFjZXNbaW50ZXJmYWNlSWRdID0gdHJ1ZTsKICAgIH0KfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy9tYXRoL1NhZmVNYXRoLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOC4wOwoKLyoqCiAqIEBkZXYgV3JhcHBlcnMgb3ZlciBTb2xpZGl0eSdzIGFyaXRobWV0aWMgb3BlcmF0aW9ucyB3aXRoIGFkZGVkIG92ZXJmbG93CiAqIGNoZWNrcy4KICoKICogQXJpdGhtZXRpYyBvcGVyYXRpb25zIGluIFNvbGlkaXR5IHdyYXAgb24gb3ZlcmZsb3cuIFRoaXMgY2FuIGVhc2lseSByZXN1bHQKICogaW4gYnVncywgYmVjYXVzZSBwcm9ncmFtbWVycyB1c3VhbGx5IGFzc3VtZSB0aGF0IGFuIG92ZXJmbG93IHJhaXNlcyBhbgogKiBlcnJvciwgd2hpY2ggaXMgdGhlIHN0YW5kYXJkIGJlaGF2aW9yIGluIGhpZ2ggbGV2ZWwgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLgogKiBgU2FmZU1hdGhgIHJlc3RvcmVzIHRoaXMgaW50dWl0aW9uIGJ5IHJldmVydGluZyB0aGUgdHJhbnNhY3Rpb24gd2hlbiBhbgogKiBvcGVyYXRpb24gb3ZlcmZsb3dzLgogKgogKiBVc2luZyB0aGlzIGxpYnJhcnkgaW5zdGVhZCBvZiB0aGUgdW5jaGVja2VkIG9wZXJhdGlvbnMgZWxpbWluYXRlcyBhbiBlbnRpcmUKICogY2xhc3Mgb2YgYnVncywgc28gaXQncyByZWNvbW1lbmRlZCB0byB1c2UgaXQgYWx3YXlzLgogKi8KbGlicmFyeSBTYWZlTWF0aCB7CiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgYWRkaXRpb24gb2YgdHdvIHVuc2lnbmVkIGludGVnZXJzLCB3aXRoIGFuIG92ZXJmbG93IGZsYWcuCiAgICAgKgogICAgICogX0F2YWlsYWJsZSBzaW5jZSB2My40Ll8KICAgICAqLwogICAgZnVuY3Rpb24gdHJ5QWRkKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJvb2wsIHVpbnQyNTYpIHsKICAgICAgICB1aW50MjU2IGMgPSBhICsgYjsKICAgICAgICBpZiAoYyA8IGEpIHJldHVybiAoZmFsc2UsIDApOwogICAgICAgIHJldHVybiAodHJ1ZSwgYyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIHN1YnN0cmFjdGlvbiBvZiB0d28gdW5zaWduZWQgaW50ZWdlcnMsIHdpdGggYW4gb3ZlcmZsb3cgZmxhZy4KICAgICAqCiAgICAgKiBfQXZhaWxhYmxlIHNpbmNlIHYzLjQuXwogICAgICovCiAgICBmdW5jdGlvbiB0cnlTdWIodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCwgdWludDI1NikgewogICAgICAgIGlmIChiID4gYSkgcmV0dXJuIChmYWxzZSwgMCk7CiAgICAgICAgcmV0dXJuICh0cnVlLCBhIC0gYik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG11bHRpcGxpY2F0aW9uIG9mIHR3byB1bnNpZ25lZCBpbnRlZ2Vycywgd2l0aCBhbiBvdmVyZmxvdyBmbGFnLgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuNC5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRyeU11bCh1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sLCB1aW50MjU2KSB7CiAgICAgICAgLy8gR2FzIG9wdGltaXphdGlvbjogdGhpcyBpcyBjaGVhcGVyIHRoYW4gcmVxdWlyaW5nICdhJyBub3QgYmVpbmcgemVybywgYnV0IHRoZQogICAgICAgIC8vIGJlbmVmaXQgaXMgbG9zdCBpZiAnYicgaXMgYWxzbyB0ZXN0ZWQuCiAgICAgICAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSByZXR1cm4gKHRydWUsIDApOwogICAgICAgIHVpbnQyNTYgYyA9IGEgKiBiOwogICAgICAgIGlmIChjIC8gYSAhPSBiKSByZXR1cm4gKGZhbHNlLCAwKTsKICAgICAgICByZXR1cm4gKHRydWUsIGMpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBkaXZpc2lvbiBvZiB0d28gdW5zaWduZWQgaW50ZWdlcnMsIHdpdGggYSBkaXZpc2lvbiBieSB6ZXJvIGZsYWcuCiAgICAgKgogICAgICogX0F2YWlsYWJsZSBzaW5jZSB2My40Ll8KICAgICAqLwogICAgZnVuY3Rpb24gdHJ5RGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJvb2wsIHVpbnQyNTYpIHsKICAgICAgICBpZiAoYiA9PSAwKSByZXR1cm4gKGZhbHNlLCAwKTsKICAgICAgICByZXR1cm4gKHRydWUsIGEgLyBiKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgcmVtYWluZGVyIG9mIGRpdmlkaW5nIHR3byB1bnNpZ25lZCBpbnRlZ2Vycywgd2l0aCBhIGRpdmlzaW9uIGJ5IHplcm8gZmxhZy4KICAgICAqCiAgICAgKiBfQXZhaWxhYmxlIHNpbmNlIHYzLjQuXwogICAgICovCiAgICBmdW5jdGlvbiB0cnlNb2QodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCwgdWludDI1NikgewogICAgICAgIGlmIChiID09IDApIHJldHVybiAoZmFsc2UsIDApOwogICAgICAgIHJldHVybiAodHJ1ZSwgYSAlIGIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBhZGRpdGlvbiBvZiB0d28gdW5zaWduZWQgaW50ZWdlcnMsIHJldmVydGluZyBvbgogICAgICogb3ZlcmZsb3cuCiAgICAgKgogICAgICogQ291bnRlcnBhcnQgdG8gU29saWRpdHkncyBgK2Agb3BlcmF0b3IuCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gQWRkaXRpb24gY2Fubm90IG92ZXJmbG93LgogICAgICovCiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CiAgICAgICAgcmV0dXJuIGM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIHN1YnRyYWN0aW9uIG9mIHR3byB1bnNpZ25lZCBpbnRlZ2VycywgcmV2ZXJ0aW5nIG9uCiAgICAgKiBvdmVyZmxvdyAod2hlbiB0aGUgcmVzdWx0IGlzIG5lZ2F0aXZlKS4KICAgICAqCiAgICAgKiBDb3VudGVycGFydCB0byBTb2xpZGl0eSdzIGAtYCBvcGVyYXRvci4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBTdWJ0cmFjdGlvbiBjYW5ub3Qgb3ZlcmZsb3cuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICByZXR1cm4gYSAtIGI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG11bHRpcGxpY2F0aW9uIG9mIHR3byB1bnNpZ25lZCBpbnRlZ2VycywgcmV2ZXJ0aW5nIG9uCiAgICAgKiBvdmVyZmxvdy4KICAgICAqCiAgICAgKiBDb3VudGVycGFydCB0byBTb2xpZGl0eSdzIGAqYCBvcGVyYXRvci4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBNdWx0aXBsaWNhdGlvbiBjYW5ub3Qgb3ZlcmZsb3cuCiAgICAgKi8KICAgIGZ1bmN0aW9uIG11bCh1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgaWYgKGEgPT0gMCkgcmV0dXJuIDA7CiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CiAgICAgICAgcmV0dXJuIGM7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIGludGVnZXIgZGl2aXNpb24gb2YgdHdvIHVuc2lnbmVkIGludGVnZXJzLCByZXZlcnRpbmcgb24KICAgICAqIGRpdmlzaW9uIGJ5IHplcm8uIFRoZSByZXN1bHQgaXMgcm91bmRlZCB0b3dhcmRzIHplcm8uCiAgICAgKgogICAgICogQ291bnRlcnBhcnQgdG8gU29saWRpdHkncyBgL2Agb3BlcmF0b3IuIE5vdGU6IHRoaXMgZnVuY3Rpb24gdXNlcyBhCiAgICAgKiBgcmV2ZXJ0YCBvcGNvZGUgKHdoaWNoIGxlYXZlcyByZW1haW5pbmcgZ2FzIHVudG91Y2hlZCkgd2hpbGUgU29saWRpdHkKICAgICAqIHVzZXMgYW4gaW52YWxpZCBvcGNvZGUgdG8gcmV2ZXJ0IChjb25zdW1pbmcgYWxsIHJlbWFpbmluZyBnYXMpLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIFRoZSBkaXZpc29yIGNhbm5vdCBiZSB6ZXJvLgogICAgICovCiAgICBmdW5jdGlvbiBkaXYodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJlcXVpcmUoYiA+IDAsICJTYWZlTWF0aDogZGl2aXNpb24gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhIC8gYjsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgcmVtYWluZGVyIG9mIGRpdmlkaW5nIHR3byB1bnNpZ25lZCBpbnRlZ2Vycy4gKHVuc2lnbmVkIGludGVnZXIgbW9kdWxvKSwKICAgICAqIHJldmVydGluZyB3aGVuIGRpdmlkaW5nIGJ5IHplcm8uCiAgICAgKgogICAgICogQ291bnRlcnBhcnQgdG8gU29saWRpdHkncyBgJWAgb3BlcmF0b3IuIFRoaXMgZnVuY3Rpb24gdXNlcyBhIGByZXZlcnRgCiAgICAgKiBvcGNvZGUgKHdoaWNoIGxlYXZlcyByZW1haW5pbmcgZ2FzIHVudG91Y2hlZCkgd2hpbGUgU29saWRpdHkgdXNlcyBhbgogICAgICogaW52YWxpZCBvcGNvZGUgdG8gcmV2ZXJ0IChjb25zdW1pbmcgYWxsIHJlbWFpbmluZyBnYXMpLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIFRoZSBkaXZpc29yIGNhbm5vdCBiZSB6ZXJvLgogICAgICovCiAgICBmdW5jdGlvbiBtb2QodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJlcXVpcmUoYiA+IDAsICJTYWZlTWF0aDogbW9kdWxvIGJ5IHplcm8iKTsKICAgICAgICByZXR1cm4gYSAlIGI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIHN1YnRyYWN0aW9uIG9mIHR3byB1bnNpZ25lZCBpbnRlZ2VycywgcmV2ZXJ0aW5nIHdpdGggY3VzdG9tIG1lc3NhZ2Ugb24KICAgICAqIG92ZXJmbG93ICh3aGVuIHRoZSByZXN1bHQgaXMgbmVnYXRpdmUpLgogICAgICoKICAgICAqIENBVVRJT046IFRoaXMgZnVuY3Rpb24gaXMgZGVwcmVjYXRlZCBiZWNhdXNlIGl0IHJlcXVpcmVzIGFsbG9jYXRpbmcgbWVtb3J5IGZvciB0aGUgZXJyb3IKICAgICAqIG1lc3NhZ2UgdW5uZWNlc3NhcmlseS4gRm9yIGN1c3RvbSByZXZlcnQgcmVhc29ucyB1c2Uge3RyeVN1Yn0uCiAgICAgKgogICAgICogQ291bnRlcnBhcnQgdG8gU29saWRpdHkncyBgLWAgb3BlcmF0b3IuCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gU3VidHJhY3Rpb24gY2Fubm90IG92ZXJmbG93LgogICAgICovCiAgICBmdW5jdGlvbiBzdWIodWludDI1NiBhLCB1aW50MjU2IGIsIHN0cmluZyBtZW1vcnkgZXJyb3JNZXNzYWdlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgPD0gYSwgZXJyb3JNZXNzYWdlKTsKICAgICAgICByZXR1cm4gYSAtIGI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIGludGVnZXIgZGl2aXNpb24gb2YgdHdvIHVuc2lnbmVkIGludGVnZXJzLCByZXZlcnRpbmcgd2l0aCBjdXN0b20gbWVzc2FnZSBvbgogICAgICogZGl2aXNpb24gYnkgemVyby4gVGhlIHJlc3VsdCBpcyByb3VuZGVkIHRvd2FyZHMgemVyby4KICAgICAqCiAgICAgKiBDQVVUSU9OOiBUaGlzIGZ1bmN0aW9uIGlzIGRlcHJlY2F0ZWQgYmVjYXVzZSBpdCByZXF1aXJlcyBhbGxvY2F0aW5nIG1lbW9yeSBmb3IgdGhlIGVycm9yCiAgICAgKiBtZXNzYWdlIHVubmVjZXNzYXJpbHkuIEZvciBjdXN0b20gcmV2ZXJ0IHJlYXNvbnMgdXNlIHt0cnlEaXZ9LgogICAgICoKICAgICAqIENvdW50ZXJwYXJ0IHRvIFNvbGlkaXR5J3MgYC9gIG9wZXJhdG9yLiBOb3RlOiB0aGlzIGZ1bmN0aW9uIHVzZXMgYQogICAgICogYHJldmVydGAgb3Bjb2RlICh3aGljaCBsZWF2ZXMgcmVtYWluaW5nIGdhcyB1bnRvdWNoZWQpIHdoaWxlIFNvbGlkaXR5CiAgICAgKiB1c2VzIGFuIGludmFsaWQgb3Bjb2RlIHRvIHJldmVydCAoY29uc3VtaW5nIGFsbCByZW1haW5pbmcgZ2FzKS4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBUaGUgZGl2aXNvciBjYW5ub3QgYmUgemVyby4KICAgICAqLwogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiLCBzdHJpbmcgbWVtb3J5IGVycm9yTWVzc2FnZSkgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiID4gMCwgZXJyb3JNZXNzYWdlKTsKICAgICAgICByZXR1cm4gYSAvIGI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIHJlbWFpbmRlciBvZiBkaXZpZGluZyB0d28gdW5zaWduZWQgaW50ZWdlcnMuICh1bnNpZ25lZCBpbnRlZ2VyIG1vZHVsbyksCiAgICAgKiByZXZlcnRpbmcgd2l0aCBjdXN0b20gbWVzc2FnZSB3aGVuIGRpdmlkaW5nIGJ5IHplcm8uCiAgICAgKgogICAgICogQ0FVVElPTjogVGhpcyBmdW5jdGlvbiBpcyBkZXByZWNhdGVkIGJlY2F1c2UgaXQgcmVxdWlyZXMgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHRoZSBlcnJvcgogICAgICogbWVzc2FnZSB1bm5lY2Vzc2FyaWx5LiBGb3IgY3VzdG9tIHJldmVydCByZWFzb25zIHVzZSB7dHJ5TW9kfS4KICAgICAqCiAgICAgKiBDb3VudGVycGFydCB0byBTb2xpZGl0eSdzIGAlYCBvcGVyYXRvci4gVGhpcyBmdW5jdGlvbiB1c2VzIGEgYHJldmVydGAKICAgICAqIG9wY29kZSAod2hpY2ggbGVhdmVzIHJlbWFpbmluZyBnYXMgdW50b3VjaGVkKSB3aGlsZSBTb2xpZGl0eSB1c2VzIGFuCiAgICAgKiBpbnZhbGlkIG9wY29kZSB0byByZXZlcnQgKGNvbnN1bWluZyBhbGwgcmVtYWluaW5nIGdhcykuCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gVGhlIGRpdmlzb3IgY2Fubm90IGJlIHplcm8uCiAgICAgKi8KICAgIGZ1bmN0aW9uIG1vZCh1aW50MjU2IGEsIHVpbnQyNTYgYiwgc3RyaW5nIG1lbW9yeSBlcnJvck1lc3NhZ2UpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJlcXVpcmUoYiA+IDAsIGVycm9yTWVzc2FnZSk7CiAgICAgICAgcmV0dXJuIGEgJSBiOwogICAgfQp9CgovLyBGaWxlOiBvcGVuemVwcGVsaW4tc29saWRpdHkvY29udHJhY3RzL3V0aWxzL0FkZHJlc3Muc29sCgovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCgpwcmFnbWEgc29saWRpdHkgPj0wLjYuMiA8MC44LjA7CgovKioKICogQGRldiBDb2xsZWN0aW9uIG9mIGZ1bmN0aW9ucyByZWxhdGVkIHRvIHRoZSBhZGRyZXNzIHR5cGUKICovCmxpYnJhcnkgQWRkcmVzcyB7CiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0cnVlIGlmIGBhY2NvdW50YCBpcyBhIGNvbnRyYWN0LgogICAgICoKICAgICAqIFtJTVBPUlRBTlRdCiAgICAgKiA9PT09CiAgICAgKiBJdCBpcyB1bnNhZmUgdG8gYXNzdW1lIHRoYXQgYW4gYWRkcmVzcyBmb3Igd2hpY2ggdGhpcyBmdW5jdGlvbiByZXR1cm5zCiAgICAgKiBmYWxzZSBpcyBhbiBleHRlcm5hbGx5LW93bmVkIGFjY291bnQgKEVPQSkgYW5kIG5vdCBhIGNvbnRyYWN0LgogICAgICoKICAgICAqIEFtb25nIG90aGVycywgYGlzQ29udHJhY3RgIHdpbGwgcmV0dXJuIGZhbHNlIGZvciB0aGUgZm9sbG93aW5nCiAgICAgKiB0eXBlcyBvZiBhZGRyZXNzZXM6CiAgICAgKgogICAgICogIC0gYW4gZXh0ZXJuYWxseS1vd25lZCBhY2NvdW50CiAgICAgKiAgLSBhIGNvbnRyYWN0IGluIGNvbnN0cnVjdGlvbgogICAgICogIC0gYW4gYWRkcmVzcyB3aGVyZSBhIGNvbnRyYWN0IHdpbGwgYmUgY3JlYXRlZAogICAgICogIC0gYW4gYWRkcmVzcyB3aGVyZSBhIGNvbnRyYWN0IGxpdmVkLCBidXQgd2FzIGRlc3Ryb3llZAogICAgICogPT09PQogICAgICovCiAgICBmdW5jdGlvbiBpc0NvbnRyYWN0KGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgLy8gVGhpcyBtZXRob2QgcmVsaWVzIG9uIGV4dGNvZGVzaXplLCB3aGljaCByZXR1cm5zIDAgZm9yIGNvbnRyYWN0cyBpbgogICAgICAgIC8vIGNvbnN0cnVjdGlvbiwgc2luY2UgdGhlIGNvZGUgaXMgb25seSBzdG9yZWQgYXQgdGhlIGVuZCBvZiB0aGUKICAgICAgICAvLyBjb25zdHJ1Y3RvciBleGVjdXRpb24uCgogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICAvLyBzb2xoaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWlubGluZS1hc3NlbWJseQogICAgICAgIGFzc2VtYmx5IHsgc2l6ZSA6PSBleHRjb2Rlc2l6ZShhY2NvdW50KSB9CiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXBsYWNlbWVudCBmb3IgU29saWRpdHkncyBgdHJhbnNmZXJgOiBzZW5kcyBgYW1vdW50YCB3ZWkgdG8KICAgICAqIGByZWNpcGllbnRgLCBmb3J3YXJkaW5nIGFsbCBhdmFpbGFibGUgZ2FzIGFuZCByZXZlcnRpbmcgb24gZXJyb3JzLgogICAgICoKICAgICAqIGh0dHBzOi8vZWlwcy5ldGhlcmV1bS5vcmcvRUlQUy9laXAtMTg4NFtFSVAxODg0XSBpbmNyZWFzZXMgdGhlIGdhcyBjb3N0CiAgICAgKiBvZiBjZXJ0YWluIG9wY29kZXMsIHBvc3NpYmx5IG1ha2luZyBjb250cmFjdHMgZ28gb3ZlciB0aGUgMjMwMCBnYXMgbGltaXQKICAgICAqIGltcG9zZWQgYnkgYHRyYW5zZmVyYCwgbWFraW5nIHRoZW0gdW5hYmxlIHRvIHJlY2VpdmUgZnVuZHMgdmlhCiAgICAgKiBgdHJhbnNmZXJgLiB7c2VuZFZhbHVlfSByZW1vdmVzIHRoaXMgbGltaXRhdGlvbi4KICAgICAqCiAgICAgKiBodHRwczovL2RpbGlnZW5jZS5jb25zZW5zeXMubmV0L3Bvc3RzLzIwMTkvMDkvc3RvcC11c2luZy1zb2xpZGl0eXMtdHJhbnNmZXItbm93L1tMZWFybiBtb3JlXS4KICAgICAqCiAgICAgKiBJTVBPUlRBTlQ6IGJlY2F1c2UgY29udHJvbCBpcyB0cmFuc2ZlcnJlZCB0byBgcmVjaXBpZW50YCwgY2FyZSBtdXN0IGJlCiAgICAgKiB0YWtlbiB0byBub3QgY3JlYXRlIHJlZW50cmFuY3kgdnVsbmVyYWJpbGl0aWVzLiBDb25zaWRlciB1c2luZwogICAgICoge1JlZW50cmFuY3lHdWFyZH0gb3IgdGhlCiAgICAgKiBodHRwczovL3NvbGlkaXR5LnJlYWR0aGVkb2NzLmlvL2VuL3YwLjUuMTEvc2VjdXJpdHktY29uc2lkZXJhdGlvbnMuaHRtbCN1c2UtdGhlLWNoZWNrcy1lZmZlY3RzLWludGVyYWN0aW9ucy1wYXR0ZXJuW2NoZWNrcy1lZmZlY3RzLWludGVyYWN0aW9ucyBwYXR0ZXJuXS4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZFZhbHVlKGFkZHJlc3MgcGF5YWJsZSByZWNpcGllbnQsIHVpbnQyNTYgYW1vdW50KSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhZGRyZXNzKHRoaXMpLmJhbGFuY2UgPj0gYW1vdW50LCAiQWRkcmVzczogaW5zdWZmaWNpZW50IGJhbGFuY2UiKTsKCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBhdm9pZC1sb3ctbGV2ZWwtY2FsbHMsIGF2b2lkLWNhbGwtdmFsdWUKICAgICAgICAoYm9vbCBzdWNjZXNzLCApID0gcmVjaXBpZW50LmNhbGx7IHZhbHVlOiBhbW91bnQgfSgiIik7CiAgICAgICAgcmVxdWlyZShzdWNjZXNzLCAiQWRkcmVzczogdW5hYmxlIHRvIHNlbmQgdmFsdWUsIHJlY2lwaWVudCBtYXkgaGF2ZSByZXZlcnRlZCIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBQZXJmb3JtcyBhIFNvbGlkaXR5IGZ1bmN0aW9uIGNhbGwgdXNpbmcgYSBsb3cgbGV2ZWwgYGNhbGxgLiBBCiAgICAgKiBwbGFpbmBjYWxsYCBpcyBhbiB1bnNhZmUgcmVwbGFjZW1lbnQgZm9yIGEgZnVuY3Rpb24gY2FsbDogdXNlIHRoaXMKICAgICAqIGZ1bmN0aW9uIGluc3RlYWQuCiAgICAgKgogICAgICogSWYgYHRhcmdldGAgcmV2ZXJ0cyB3aXRoIGEgcmV2ZXJ0IHJlYXNvbiwgaXQgaXMgYnViYmxlZCB1cCBieSB0aGlzCiAgICAgKiBmdW5jdGlvbiAobGlrZSByZWd1bGFyIFNvbGlkaXR5IGZ1bmN0aW9uIGNhbGxzKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRoZSByYXcgcmV0dXJuZWQgZGF0YS4gVG8gY29udmVydCB0byB0aGUgZXhwZWN0ZWQgcmV0dXJuIHZhbHVlLAogICAgICogdXNlIGh0dHBzOi8vc29saWRpdHkucmVhZHRoZWRvY3MuaW8vZW4vbGF0ZXN0L3VuaXRzLWFuZC1nbG9iYWwtdmFyaWFibGVzLmh0bWw/aGlnaGxpZ2h0PWFiaS5kZWNvZGUjYWJpLWVuY29kaW5nLWFuZC1kZWNvZGluZy1mdW5jdGlvbnNbYGFiaS5kZWNvZGVgXS4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBgdGFyZ2V0YCBtdXN0IGJlIGEgY29udHJhY3QuCiAgICAgKiAtIGNhbGxpbmcgYHRhcmdldGAgd2l0aCBgZGF0YWAgbXVzdCBub3QgcmV2ZXJ0LgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuMS5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIGZ1bmN0aW9uQ2FsbChhZGRyZXNzIHRhcmdldCwgYnl0ZXMgbWVtb3J5IGRhdGEpIGludGVybmFsIHJldHVybnMgKGJ5dGVzIG1lbW9yeSkgewogICAgICByZXR1cm4gZnVuY3Rpb25DYWxsKHRhcmdldCwgZGF0YSwgIkFkZHJlc3M6IGxvdy1sZXZlbCBjYWxsIGZhaWxlZCIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTYW1lIGFzIHt4cmVmLUFkZHJlc3MtZnVuY3Rpb25DYWxsLWFkZHJlc3MtYnl0ZXMtfVtgZnVuY3Rpb25DYWxsYF0sIGJ1dCB3aXRoCiAgICAgKiBgZXJyb3JNZXNzYWdlYCBhcyBhIGZhbGxiYWNrIHJldmVydCByZWFzb24gd2hlbiBgdGFyZ2V0YCByZXZlcnRzLgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuMS5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIGZ1bmN0aW9uQ2FsbChhZGRyZXNzIHRhcmdldCwgYnl0ZXMgbWVtb3J5IGRhdGEsIHN0cmluZyBtZW1vcnkgZXJyb3JNZXNzYWdlKSBpbnRlcm5hbCByZXR1cm5zIChieXRlcyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb25DYWxsV2l0aFZhbHVlKHRhcmdldCwgZGF0YSwgMCwgZXJyb3JNZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2FtZSBhcyB7eHJlZi1BZGRyZXNzLWZ1bmN0aW9uQ2FsbC1hZGRyZXNzLWJ5dGVzLX1bYGZ1bmN0aW9uQ2FsbGBdLAogICAgICogYnV0IGFsc28gdHJhbnNmZXJyaW5nIGB2YWx1ZWAgd2VpIHRvIGB0YXJnZXRgLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIHRoZSBjYWxsaW5nIGNvbnRyYWN0IG11c3QgaGF2ZSBhbiBFVEggYmFsYW5jZSBvZiBhdCBsZWFzdCBgdmFsdWVgLgogICAgICogLSB0aGUgY2FsbGVkIFNvbGlkaXR5IGZ1bmN0aW9uIG11c3QgYmUgYHBheWFibGVgLgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuMS5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIGZ1bmN0aW9uQ2FsbFdpdGhWYWx1ZShhZGRyZXNzIHRhcmdldCwgYnl0ZXMgbWVtb3J5IGRhdGEsIHVpbnQyNTYgdmFsdWUpIGludGVybmFsIHJldHVybnMgKGJ5dGVzIG1lbW9yeSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbkNhbGxXaXRoVmFsdWUodGFyZ2V0LCBkYXRhLCB2YWx1ZSwgIkFkZHJlc3M6IGxvdy1sZXZlbCBjYWxsIHdpdGggdmFsdWUgZmFpbGVkIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNhbWUgYXMge3hyZWYtQWRkcmVzcy1mdW5jdGlvbkNhbGxXaXRoVmFsdWUtYWRkcmVzcy1ieXRlcy11aW50MjU2LX1bYGZ1bmN0aW9uQ2FsbFdpdGhWYWx1ZWBdLCBidXQKICAgICAqIHdpdGggYGVycm9yTWVzc2FnZWAgYXMgYSBmYWxsYmFjayByZXZlcnQgcmVhc29uIHdoZW4gYHRhcmdldGAgcmV2ZXJ0cy4KICAgICAqCiAgICAgKiBfQXZhaWxhYmxlIHNpbmNlIHYzLjEuXwogICAgICovCiAgICBmdW5jdGlvbiBmdW5jdGlvbkNhbGxXaXRoVmFsdWUoYWRkcmVzcyB0YXJnZXQsIGJ5dGVzIG1lbW9yeSBkYXRhLCB1aW50MjU2IHZhbHVlLCBzdHJpbmcgbWVtb3J5IGVycm9yTWVzc2FnZSkgaW50ZXJuYWwgcmV0dXJucyAoYnl0ZXMgbWVtb3J5KSB7CiAgICAgICAgcmVxdWlyZShhZGRyZXNzKHRoaXMpLmJhbGFuY2UgPj0gdmFsdWUsICJBZGRyZXNzOiBpbnN1ZmZpY2llbnQgYmFsYW5jZSBmb3IgY2FsbCIpOwogICAgICAgIHJlcXVpcmUoaXNDb250cmFjdCh0YXJnZXQpLCAiQWRkcmVzczogY2FsbCB0byBub24tY29udHJhY3QiKTsKCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBhdm9pZC1sb3ctbGV2ZWwtY2FsbHMKICAgICAgICAoYm9vbCBzdWNjZXNzLCBieXRlcyBtZW1vcnkgcmV0dXJuZGF0YSkgPSB0YXJnZXQuY2FsbHsgdmFsdWU6IHZhbHVlIH0oZGF0YSk7CiAgICAgICAgcmV0dXJuIF92ZXJpZnlDYWxsUmVzdWx0KHN1Y2Nlc3MsIHJldHVybmRhdGEsIGVycm9yTWVzc2FnZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNhbWUgYXMge3hyZWYtQWRkcmVzcy1mdW5jdGlvbkNhbGwtYWRkcmVzcy1ieXRlcy19W2BmdW5jdGlvbkNhbGxgXSwKICAgICAqIGJ1dCBwZXJmb3JtaW5nIGEgc3RhdGljIGNhbGwuCiAgICAgKgogICAgICogX0F2YWlsYWJsZSBzaW5jZSB2My4zLl8KICAgICAqLwogICAgZnVuY3Rpb24gZnVuY3Rpb25TdGF0aWNDYWxsKGFkZHJlc3MgdGFyZ2V0LCBieXRlcyBtZW1vcnkgZGF0YSkgaW50ZXJuYWwgdmlldyByZXR1cm5zIChieXRlcyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb25TdGF0aWNDYWxsKHRhcmdldCwgZGF0YSwgIkFkZHJlc3M6IGxvdy1sZXZlbCBzdGF0aWMgY2FsbCBmYWlsZWQiKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2FtZSBhcyB7eHJlZi1BZGRyZXNzLWZ1bmN0aW9uQ2FsbC1hZGRyZXNzLWJ5dGVzLXN0cmluZy19W2BmdW5jdGlvbkNhbGxgXSwKICAgICAqIGJ1dCBwZXJmb3JtaW5nIGEgc3RhdGljIGNhbGwuCiAgICAgKgogICAgICogX0F2YWlsYWJsZSBzaW5jZSB2My4zLl8KICAgICAqLwogICAgZnVuY3Rpb24gZnVuY3Rpb25TdGF0aWNDYWxsKGFkZHJlc3MgdGFyZ2V0LCBieXRlcyBtZW1vcnkgZGF0YSwgc3RyaW5nIG1lbW9yeSBlcnJvck1lc3NhZ2UpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYnl0ZXMgbWVtb3J5KSB7CiAgICAgICAgcmVxdWlyZShpc0NvbnRyYWN0KHRhcmdldCksICJBZGRyZXNzOiBzdGF0aWMgY2FsbCB0byBub24tY29udHJhY3QiKTsKCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBhdm9pZC1sb3ctbGV2ZWwtY2FsbHMKICAgICAgICAoYm9vbCBzdWNjZXNzLCBieXRlcyBtZW1vcnkgcmV0dXJuZGF0YSkgPSB0YXJnZXQuc3RhdGljY2FsbChkYXRhKTsKICAgICAgICByZXR1cm4gX3ZlcmlmeUNhbGxSZXN1bHQoc3VjY2VzcywgcmV0dXJuZGF0YSwgZXJyb3JNZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2FtZSBhcyB7eHJlZi1BZGRyZXNzLWZ1bmN0aW9uQ2FsbC1hZGRyZXNzLWJ5dGVzLX1bYGZ1bmN0aW9uQ2FsbGBdLAogICAgICogYnV0IHBlcmZvcm1pbmcgYSBkZWxlZ2F0ZSBjYWxsLgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuNC5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIGZ1bmN0aW9uRGVsZWdhdGVDYWxsKGFkZHJlc3MgdGFyZ2V0LCBieXRlcyBtZW1vcnkgZGF0YSkgaW50ZXJuYWwgcmV0dXJucyAoYnl0ZXMgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uRGVsZWdhdGVDYWxsKHRhcmdldCwgZGF0YSwgIkFkZHJlc3M6IGxvdy1sZXZlbCBkZWxlZ2F0ZSBjYWxsIGZhaWxlZCIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTYW1lIGFzIHt4cmVmLUFkZHJlc3MtZnVuY3Rpb25DYWxsLWFkZHJlc3MtYnl0ZXMtc3RyaW5nLX1bYGZ1bmN0aW9uQ2FsbGBdLAogICAgICogYnV0IHBlcmZvcm1pbmcgYSBkZWxlZ2F0ZSBjYWxsLgogICAgICoKICAgICAqIF9BdmFpbGFibGUgc2luY2UgdjMuNC5fCiAgICAgKi8KICAgIGZ1bmN0aW9uIGZ1bmN0aW9uRGVsZWdhdGVDYWxsKGFkZHJlc3MgdGFyZ2V0LCBieXRlcyBtZW1vcnkgZGF0YSwgc3RyaW5nIG1lbW9yeSBlcnJvck1lc3NhZ2UpIGludGVybmFsIHJldHVybnMgKGJ5dGVzIG1lbW9yeSkgewogICAgICAgIHJlcXVpcmUoaXNDb250cmFjdCh0YXJnZXQpLCAiQWRkcmVzczogZGVsZWdhdGUgY2FsbCB0byBub24tY29udHJhY3QiKTsKCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBhdm9pZC1sb3ctbGV2ZWwtY2FsbHMKICAgICAgICAoYm9vbCBzdWNjZXNzLCBieXRlcyBtZW1vcnkgcmV0dXJuZGF0YSkgPSB0YXJnZXQuZGVsZWdhdGVjYWxsKGRhdGEpOwogICAgICAgIHJldHVybiBfdmVyaWZ5Q2FsbFJlc3VsdChzdWNjZXNzLCByZXR1cm5kYXRhLCBlcnJvck1lc3NhZ2UpOwogICAgfQoKICAgIGZ1bmN0aW9uIF92ZXJpZnlDYWxsUmVzdWx0KGJvb2wgc3VjY2VzcywgYnl0ZXMgbWVtb3J5IHJldHVybmRhdGEsIHN0cmluZyBtZW1vcnkgZXJyb3JNZXNzYWdlKSBwcml2YXRlIHB1cmUgcmV0dXJucyhieXRlcyBtZW1vcnkpIHsKICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICByZXR1cm4gcmV0dXJuZGF0YTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBMb29rIGZvciByZXZlcnQgcmVhc29uIGFuZCBidWJibGUgaXQgdXAgaWYgcHJlc2VudAogICAgICAgICAgICBpZiAocmV0dXJuZGF0YS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAvLyBUaGUgZWFzaWVzdCB3YXkgdG8gYnViYmxlIHRoZSByZXZlcnQgcmVhc29uIGlzIHVzaW5nIG1lbW9yeSB2aWEgYXNzZW1ibHkKCiAgICAgICAgICAgICAgICAvLyBzb2xoaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWlubGluZS1hc3NlbWJseQogICAgICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgICAgIGxldCByZXR1cm5kYXRhX3NpemUgOj0gbWxvYWQocmV0dXJuZGF0YSkKICAgICAgICAgICAgICAgICAgICByZXZlcnQoYWRkKDMyLCByZXR1cm5kYXRhKSwgcmV0dXJuZGF0YV9zaXplKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV2ZXJ0KGVycm9yTWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8vIEZpbGU6IG9wZW56ZXBwZWxpbi1zb2xpZGl0eS9jb250cmFjdHMvdXRpbHMvRW51bWVyYWJsZVNldC5zb2wKCi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKCnByYWdtYSBzb2xpZGl0eSA+PTAuNi4wIDwwLjguMDsKCi8qKgogKiBAZGV2IExpYnJhcnkgZm9yIG1hbmFnaW5nCiAqIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NldF8oYWJzdHJhY3RfZGF0YV90eXBlKVtzZXRzXSBvZiBwcmltaXRpdmUKICogdHlwZXMuCiAqCiAqIFNldHMgaGF2ZSB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6CiAqCiAqIC0gRWxlbWVudHMgYXJlIGFkZGVkLCByZW1vdmVkLCBhbmQgY2hlY2tlZCBmb3IgZXhpc3RlbmNlIGluIGNvbnN0YW50IHRpbWUKICogKE8oMSkpLgogKiAtIEVsZW1lbnRzIGFyZSBlbnVtZXJhdGVkIGluIE8obikuIE5vIGd1YXJhbnRlZXMgYXJlIG1hZGUgb24gdGhlIG9yZGVyaW5nLgogKgogKiBgYGAKICogY29udHJhY3QgRXhhbXBsZSB7CiAqICAgICAvLyBBZGQgdGhlIGxpYnJhcnkgbWV0aG9kcwogKiAgICAgdXNpbmcgRW51bWVyYWJsZVNldCBmb3IgRW51bWVyYWJsZVNldC5BZGRyZXNzU2V0OwogKgogKiAgICAgLy8gRGVjbGFyZSBhIHNldCBzdGF0ZSB2YXJpYWJsZQogKiAgICAgRW51bWVyYWJsZVNldC5BZGRyZXNzU2V0IHByaXZhdGUgbXlTZXQ7CiAqIH0KICogYGBgCiAqCiAqIEFzIG9mIHYzLjMuMCwgc2V0cyBvZiB0eXBlIGBieXRlczMyYCAoYEJ5dGVzMzJTZXRgKSwgYGFkZHJlc3NgIChgQWRkcmVzc1NldGApCiAqIGFuZCBgdWludDI1NmAgKGBVaW50U2V0YCkgYXJlIHN1cHBvcnRlZC4KICovCmxpYnJhcnkgRW51bWVyYWJsZVNldCB7CiAgICAvLyBUbyBpbXBsZW1lbnQgdGhpcyBsaWJyYXJ5IGZvciBtdWx0aXBsZSB0eXBlcyB3aXRoIGFzIGxpdHRsZSBjb2RlCiAgICAvLyByZXBldGl0aW9uIGFzIHBvc3NpYmxlLCB3ZSB3cml0ZSBpdCBpbiB0ZXJtcyBvZiBhIGdlbmVyaWMgU2V0IHR5cGUgd2l0aAogICAgLy8gYnl0ZXMzMiB2YWx1ZXMuCiAgICAvLyBUaGUgU2V0IGltcGxlbWVudGF0aW9uIHVzZXMgcHJpdmF0ZSBmdW5jdGlvbnMsIGFuZCB1c2VyLWZhY2luZwogICAgLy8gaW1wbGVtZW50YXRpb25zIChzdWNoIGFzIEFkZHJlc3NTZXQpIGFyZSBqdXN0IHdyYXBwZXJzIGFyb3VuZCB0aGUKICAgIC8vIHVuZGVybHlpbmcgU2V0LgogICAgLy8gVGhpcyBtZWFucyB0aGF0IHdlIGNhbiBvbmx5IGNyZWF0ZSBuZXcgRW51bWVyYWJsZVNldHMgZm9yIHR5cGVzIHRoYXQgZml0CiAgICAvLyBpbiBieXRlczMyLgoKICAgIHN0cnVjdCBTZXQgewogICAgICAgIC8vIFN0b3JhZ2Ugb2Ygc2V0IHZhbHVlcwogICAgICAgIGJ5dGVzMzJbXSBfdmFsdWVzOwoKICAgICAgICAvLyBQb3NpdGlvbiBvZiB0aGUgdmFsdWUgaW4gdGhlIGB2YWx1ZXNgIGFycmF5LCBwbHVzIDEgYmVjYXVzZSBpbmRleCAwCiAgICAgICAgLy8gbWVhbnMgYSB2YWx1ZSBpcyBub3QgaW4gdGhlIHNldC4KICAgICAgICBtYXBwaW5nIChieXRlczMyID0+IHVpbnQyNTYpIF9pbmRleGVzOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBBZGQgYSB2YWx1ZSB0byBhIHNldC4gTygxKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHZhbHVlIHdhcyBhZGRlZCB0byB0aGUgc2V0LCB0aGF0IGlzIGlmIGl0IHdhcyBub3QKICAgICAqIGFscmVhZHkgcHJlc2VudC4KICAgICAqLwogICAgZnVuY3Rpb24gX2FkZChTZXQgc3RvcmFnZSBzZXQsIGJ5dGVzMzIgdmFsdWUpIHByaXZhdGUgcmV0dXJucyAoYm9vbCkgewogICAgICAgIGlmICghX2NvbnRhaW5zKHNldCwgdmFsdWUpKSB7CiAgICAgICAgICAgIHNldC5fdmFsdWVzLnB1c2godmFsdWUpOwogICAgICAgICAgICAvLyBUaGUgdmFsdWUgaXMgc3RvcmVkIGF0IGxlbmd0aC0xLCBidXQgd2UgYWRkIDEgdG8gYWxsIGluZGV4ZXMKICAgICAgICAgICAgLy8gYW5kIHVzZSAwIGFzIGEgc2VudGluZWwgdmFsdWUKICAgICAgICAgICAgc2V0Ll9pbmRleGVzW3ZhbHVlXSA9IHNldC5fdmFsdWVzLmxlbmd0aDsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmVtb3ZlcyBhIHZhbHVlIGZyb20gYSBzZXQuIE8oMSkuCiAgICAgKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBzZXQsIHRoYXQgaXMgaWYgaXQgd2FzCiAgICAgKiBwcmVzZW50LgogICAgICovCiAgICBmdW5jdGlvbiBfcmVtb3ZlKFNldCBzdG9yYWdlIHNldCwgYnl0ZXMzMiB2YWx1ZSkgcHJpdmF0ZSByZXR1cm5zIChib29sKSB7CiAgICAgICAgLy8gV2UgcmVhZCBhbmQgc3RvcmUgdGhlIHZhbHVlJ3MgaW5kZXggdG8gcHJldmVudCBtdWx0aXBsZSByZWFkcyBmcm9tIHRoZSBzYW1lIHN0b3JhZ2Ugc2xvdAogICAgICAgIHVpbnQyNTYgdmFsdWVJbmRleCA9IHNldC5faW5kZXhlc1t2YWx1ZV07CgogICAgICAgIGlmICh2YWx1ZUluZGV4ICE9IDApIHsgLy8gRXF1aXZhbGVudCB0byBjb250YWlucyhzZXQsIHZhbHVlKQogICAgICAgICAgICAvLyBUbyBkZWxldGUgYW4gZWxlbWVudCBmcm9tIHRoZSBfdmFsdWVzIGFycmF5IGluIE8oMSksIHdlIHN3YXAgdGhlIGVsZW1lbnQgdG8gZGVsZXRlIHdpdGggdGhlIGxhc3Qgb25lIGluCiAgICAgICAgICAgIC8vIHRoZSBhcnJheSwgYW5kIHRoZW4gcmVtb3ZlIHRoZSBsYXN0IGVsZW1lbnQgKHNvbWV0aW1lcyBjYWxsZWQgYXMgJ3N3YXAgYW5kIHBvcCcpLgogICAgICAgICAgICAvLyBUaGlzIG1vZGlmaWVzIHRoZSBvcmRlciBvZiB0aGUgYXJyYXksIGFzIG5vdGVkIGluIHthdH0uCgogICAgICAgICAgICB1aW50MjU2IHRvRGVsZXRlSW5kZXggPSB2YWx1ZUluZGV4IC0gMTsKICAgICAgICAgICAgdWludDI1NiBsYXN0SW5kZXggPSBzZXQuX3ZhbHVlcy5sZW5ndGggLSAxOwoKICAgICAgICAgICAgLy8gV2hlbiB0aGUgdmFsdWUgdG8gZGVsZXRlIGlzIHRoZSBsYXN0IG9uZSwgdGhlIHN3YXAgb3BlcmF0aW9uIGlzIHVubmVjZXNzYXJ5LiBIb3dldmVyLCBzaW5jZSB0aGlzIG9jY3VycwogICAgICAgICAgICAvLyBzbyByYXJlbHksIHdlIHN0aWxsIGRvIHRoZSBzd2FwIGFueXdheSB0byBhdm9pZCB0aGUgZ2FzIGNvc3Qgb2YgYWRkaW5nIGFuICdpZicgc3RhdGVtZW50LgoKICAgICAgICAgICAgYnl0ZXMzMiBsYXN0dmFsdWUgPSBzZXQuX3ZhbHVlc1tsYXN0SW5kZXhdOwoKICAgICAgICAgICAgLy8gTW92ZSB0aGUgbGFzdCB2YWx1ZSB0byB0aGUgaW5kZXggd2hlcmUgdGhlIHZhbHVlIHRvIGRlbGV0ZSBpcwogICAgICAgICAgICBzZXQuX3ZhbHVlc1t0b0RlbGV0ZUluZGV4XSA9IGxhc3R2YWx1ZTsKICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBpbmRleCBmb3IgdGhlIG1vdmVkIHZhbHVlCiAgICAgICAgICAgIHNldC5faW5kZXhlc1tsYXN0dmFsdWVdID0gdG9EZWxldGVJbmRleCArIDE7IC8vIEFsbCBpbmRleGVzIGFyZSAxLWJhc2VkCgogICAgICAgICAgICAvLyBEZWxldGUgdGhlIHNsb3Qgd2hlcmUgdGhlIG1vdmVkIHZhbHVlIHdhcyBzdG9yZWQKICAgICAgICAgICAgc2V0Ll92YWx1ZXMucG9wKCk7CgogICAgICAgICAgICAvLyBEZWxldGUgdGhlIGluZGV4IGZvciB0aGUgZGVsZXRlZCBzbG90CiAgICAgICAgICAgIGRlbGV0ZSBzZXQuX2luZGV4ZXNbdmFsdWVdOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBpbiB0aGUgc2V0LiBPKDEpLgogICAgICovCiAgICBmdW5jdGlvbiBfY29udGFpbnMoU2V0IHN0b3JhZ2Ugc2V0LCBieXRlczMyIHZhbHVlKSBwcml2YXRlIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBzZXQuX2luZGV4ZXNbdmFsdWVdICE9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG51bWJlciBvZiB2YWx1ZXMgb24gdGhlIHNldC4gTygxKS4KICAgICAqLwogICAgZnVuY3Rpb24gX2xlbmd0aChTZXQgc3RvcmFnZSBzZXQpIHByaXZhdGUgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIHNldC5fdmFsdWVzLmxlbmd0aDsKICAgIH0KCiAgIC8qKgogICAgKiBAZGV2IFJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBhdCBwb3NpdGlvbiBgaW5kZXhgIGluIHRoZSBzZXQuIE8oMSkuCiAgICAqCiAgICAqIE5vdGUgdGhhdCB0aGVyZSBhcmUgbm8gZ3VhcmFudGVlcyBvbiB0aGUgb3JkZXJpbmcgb2YgdmFsdWVzIGluc2lkZSB0aGUKICAgICogYXJyYXksIGFuZCBpdCBtYXkgY2hhbmdlIHdoZW4gbW9yZSB2YWx1ZXMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuCiAgICAqCiAgICAqIFJlcXVpcmVtZW50czoKICAgICoKICAgICogLSBgaW5kZXhgIG11c3QgYmUgc3RyaWN0bHkgbGVzcyB0aGFuIHtsZW5ndGh9LgogICAgKi8KICAgIGZ1bmN0aW9uIF9hdChTZXQgc3RvcmFnZSBzZXQsIHVpbnQyNTYgaW5kZXgpIHByaXZhdGUgdmlldyByZXR1cm5zIChieXRlczMyKSB7CiAgICAgICAgcmVxdWlyZShzZXQuX3ZhbHVlcy5sZW5ndGggPiBpbmRleCwgIkVudW1lcmFibGVTZXQ6IGluZGV4IG91dCBvZiBib3VuZHMiKTsKICAgICAgICByZXR1cm4gc2V0Ll92YWx1ZXNbaW5kZXhdOwogICAgfQoKICAgIC8vIEJ5dGVzMzJTZXQKCiAgICBzdHJ1Y3QgQnl0ZXMzMlNldCB7CiAgICAgICAgU2V0IF9pbm5lcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQWRkIGEgdmFsdWUgdG8gYSBzZXQuIE8oMSkuCiAgICAgKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSB3YXMgYWRkZWQgdG8gdGhlIHNldCwgdGhhdCBpcyBpZiBpdCB3YXMgbm90CiAgICAgKiBhbHJlYWR5IHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFkZChCeXRlczMyU2V0IHN0b3JhZ2Ugc2V0LCBieXRlczMyIHZhbHVlKSBpbnRlcm5hbCByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9hZGQoc2V0Ll9pbm5lciwgdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZW1vdmVzIGEgdmFsdWUgZnJvbSBhIHNldC4gTygxKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHZhbHVlIHdhcyByZW1vdmVkIGZyb20gdGhlIHNldCwgdGhhdCBpcyBpZiBpdCB3YXMKICAgICAqIHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJlbW92ZShCeXRlczMyU2V0IHN0b3JhZ2Ugc2V0LCBieXRlczMyIHZhbHVlKSBpbnRlcm5hbCByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9yZW1vdmUoc2V0Ll9pbm5lciwgdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRydWUgaWYgdGhlIHZhbHVlIGlzIGluIHRoZSBzZXQuIE8oMSkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGNvbnRhaW5zKEJ5dGVzMzJTZXQgc3RvcmFnZSBzZXQsIGJ5dGVzMzIgdmFsdWUpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfY29udGFpbnMoc2V0Ll9pbm5lciwgdmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdmFsdWVzIGluIHRoZSBzZXQuIE8oMSkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGxlbmd0aChCeXRlczMyU2V0IHN0b3JhZ2Ugc2V0KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2xlbmd0aChzZXQuX2lubmVyKTsKICAgIH0KCiAgIC8qKgogICAgKiBAZGV2IFJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBhdCBwb3NpdGlvbiBgaW5kZXhgIGluIHRoZSBzZXQuIE8oMSkuCiAgICAqCiAgICAqIE5vdGUgdGhhdCB0aGVyZSBhcmUgbm8gZ3VhcmFudGVlcyBvbiB0aGUgb3JkZXJpbmcgb2YgdmFsdWVzIGluc2lkZSB0aGUKICAgICogYXJyYXksIGFuZCBpdCBtYXkgY2hhbmdlIHdoZW4gbW9yZSB2YWx1ZXMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuCiAgICAqCiAgICAqIFJlcXVpcmVtZW50czoKICAgICoKICAgICogLSBgaW5kZXhgIG11c3QgYmUgc3RyaWN0bHkgbGVzcyB0aGFuIHtsZW5ndGh9LgogICAgKi8KICAgIGZ1bmN0aW9uIGF0KEJ5dGVzMzJTZXQgc3RvcmFnZSBzZXQsIHVpbnQyNTYgaW5kZXgpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYnl0ZXMzMikgewogICAgICAgIHJldHVybiBfYXQoc2V0Ll9pbm5lciwgaW5kZXgpOwogICAgfQoKICAgIC8vIEFkZHJlc3NTZXQKCiAgICBzdHJ1Y3QgQWRkcmVzc1NldCB7CiAgICAgICAgU2V0IF9pbm5lcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQWRkIGEgdmFsdWUgdG8gYSBzZXQuIE8oMSkuCiAgICAgKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSB3YXMgYWRkZWQgdG8gdGhlIHNldCwgdGhhdCBpcyBpZiBpdCB3YXMgbm90CiAgICAgKiBhbHJlYWR5IHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFkZChBZGRyZXNzU2V0IHN0b3JhZ2Ugc2V0LCBhZGRyZXNzIHZhbHVlKSBpbnRlcm5hbCByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9hZGQoc2V0Ll9pbm5lciwgYnl0ZXMzMih1aW50MjU2KHVpbnQxNjAodmFsdWUpKSkpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZW1vdmVzIGEgdmFsdWUgZnJvbSBhIHNldC4gTygxKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHZhbHVlIHdhcyByZW1vdmVkIGZyb20gdGhlIHNldCwgdGhhdCBpcyBpZiBpdCB3YXMKICAgICAqIHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJlbW92ZShBZGRyZXNzU2V0IHN0b3JhZ2Ugc2V0LCBhZGRyZXNzIHZhbHVlKSBpbnRlcm5hbCByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9yZW1vdmUoc2V0Ll9pbm5lciwgYnl0ZXMzMih1aW50MjU2KHVpbnQxNjAodmFsdWUpKSkpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRydWUgaWYgdGhlIHZhbHVlIGlzIGluIHRoZSBzZXQuIE8oMSkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGNvbnRhaW5zKEFkZHJlc3NTZXQgc3RvcmFnZSBzZXQsIGFkZHJlc3MgdmFsdWUpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfY29udGFpbnMoc2V0Ll9pbm5lciwgYnl0ZXMzMih1aW50MjU2KHVpbnQxNjAodmFsdWUpKSkpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdmFsdWVzIGluIHRoZSBzZXQuIE8oMSkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGxlbmd0aChBZGRyZXNzU2V0IHN0b3JhZ2Ugc2V0KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2xlbmd0aChzZXQuX2lubmVyKTsKICAgIH0KCiAgIC8qKgogICAgKiBAZGV2IFJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBhdCBwb3NpdGlvbiBgaW5kZXhgIGluIHRoZSBzZXQuIE8oMSkuCiAgICAqCiAgICAqIE5vdGUgdGhhdCB0aGVyZSBhcmUgbm8gZ3VhcmFudGVlcyBvbiB0aGUgb3JkZXJpbmcgb2YgdmFsdWVzIGluc2lkZSB0aGUKICAgICogYXJyYXksIGFuZCBpdCBtYXkgY2hhbmdlIHdoZW4gbW9yZSB2YWx1ZXMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuCiAgICAqCiAgICAqIFJlcXVpcmVtZW50czoKICAgICoKICAgICogLSBgaW5kZXhgIG11c3QgYmUgc3RyaWN0bHkgbGVzcyB0aGFuIHtsZW5ndGh9LgogICAgKi8KICAgIGZ1bmN0aW9uIGF0KEFkZHJlc3NTZXQgc3RvcmFnZSBzZXQsIHVpbnQyNTYgaW5kZXgpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYWRkcmVzcykgewogICAgICAgIHJldHVybiBhZGRyZXNzKHVpbnQxNjAodWludDI1NihfYXQoc2V0Ll9pbm5lciwgaW5kZXgpKSkpOwogICAgfQoKCiAgICAvLyBVaW50U2V0CgogICAgc3RydWN0IFVpbnRTZXQgewogICAgICAgIFNldCBfaW5uZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEFkZCBhIHZhbHVlIHRvIGEgc2V0LiBPKDEpLgogICAgICoKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdmFsdWUgd2FzIGFkZGVkIHRvIHRoZSBzZXQsIHRoYXQgaXMgaWYgaXQgd2FzIG5vdAogICAgICogYWxyZWFkeSBwcmVzZW50LgogICAgICovCiAgICBmdW5jdGlvbiBhZGQoVWludFNldCBzdG9yYWdlIHNldCwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfYWRkKHNldC5faW5uZXIsIGJ5dGVzMzIodmFsdWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmVtb3ZlcyBhIHZhbHVlIGZyb20gYSBzZXQuIE8oMSkuCiAgICAgKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBzZXQsIHRoYXQgaXMgaWYgaXQgd2FzCiAgICAgKiBwcmVzZW50LgogICAgICovCiAgICBmdW5jdGlvbiByZW1vdmUoVWludFNldCBzdG9yYWdlIHNldCwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfcmVtb3ZlKHNldC5faW5uZXIsIGJ5dGVzMzIodmFsdWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBpbiB0aGUgc2V0LiBPKDEpLgogICAgICovCiAgICBmdW5jdGlvbiBjb250YWlucyhVaW50U2V0IHN0b3JhZ2Ugc2V0LCB1aW50MjU2IHZhbHVlKSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX2NvbnRhaW5zKHNldC5faW5uZXIsIGJ5dGVzMzIodmFsdWUpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgbnVtYmVyIG9mIHZhbHVlcyBvbiB0aGUgc2V0LiBPKDEpLgogICAgICovCiAgICBmdW5jdGlvbiBsZW5ndGgoVWludFNldCBzdG9yYWdlIHNldCkgaW50ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9sZW5ndGgoc2V0Ll9pbm5lcik7CiAgICB9CgogICAvKioKICAgICogQGRldiBSZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgcG9zaXRpb24gYGluZGV4YCBpbiB0aGUgc2V0LiBPKDEpLgogICAgKgogICAgKiBOb3RlIHRoYXQgdGhlcmUgYXJlIG5vIGd1YXJhbnRlZXMgb24gdGhlIG9yZGVyaW5nIG9mIHZhbHVlcyBpbnNpZGUgdGhlCiAgICAqIGFycmF5LCBhbmQgaXQgbWF5IGNoYW5nZSB3aGVuIG1vcmUgdmFsdWVzIGFyZSBhZGRlZCBvciByZW1vdmVkLgogICAgKgogICAgKiBSZXF1aXJlbWVudHM6CiAgICAqCiAgICAqIC0gYGluZGV4YCBtdXN0IGJlIHN0cmljdGx5IGxlc3MgdGhhbiB7bGVuZ3RofS4KICAgICovCiAgICBmdW5jdGlvbiBhdChVaW50U2V0IHN0b3JhZ2Ugc2V0LCB1aW50MjU2IGluZGV4KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gdWludDI1NihfYXQoc2V0Ll9pbm5lciwgaW5kZXgpKTsKICAgIH0KfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy91dGlscy9FbnVtZXJhYmxlTWFwLnNvbAoKLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAoKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOC4wOwoKLyoqCiAqIEBkZXYgTGlicmFyeSBmb3IgbWFuYWdpbmcgYW4gZW51bWVyYWJsZSB2YXJpYW50IG9mIFNvbGlkaXR5J3MKICogaHR0cHM6Ly9zb2xpZGl0eS5yZWFkdGhlZG9jcy5pby9lbi9sYXRlc3QvdHlwZXMuaHRtbCNtYXBwaW5nLXR5cGVzW2BtYXBwaW5nYF0KICogdHlwZS4KICoKICogTWFwcyBoYXZlIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoKICoKICogLSBFbnRyaWVzIGFyZSBhZGRlZCwgcmVtb3ZlZCwgYW5kIGNoZWNrZWQgZm9yIGV4aXN0ZW5jZSBpbiBjb25zdGFudCB0aW1lCiAqIChPKDEpKS4KICogLSBFbnRyaWVzIGFyZSBlbnVtZXJhdGVkIGluIE8obikuIE5vIGd1YXJhbnRlZXMgYXJlIG1hZGUgb24gdGhlIG9yZGVyaW5nLgogKgogKiBgYGAKICogY29udHJhY3QgRXhhbXBsZSB7CiAqICAgICAvLyBBZGQgdGhlIGxpYnJhcnkgbWV0aG9kcwogKiAgICAgdXNpbmcgRW51bWVyYWJsZU1hcCBmb3IgRW51bWVyYWJsZU1hcC5VaW50VG9BZGRyZXNzTWFwOwogKgogKiAgICAgLy8gRGVjbGFyZSBhIHNldCBzdGF0ZSB2YXJpYWJsZQogKiAgICAgRW51bWVyYWJsZU1hcC5VaW50VG9BZGRyZXNzTWFwIHByaXZhdGUgbXlNYXA7CiAqIH0KICogYGBgCiAqCiAqIEFzIG9mIHYzLjAuMCwgb25seSBtYXBzIG9mIHR5cGUgYHVpbnQyNTYgLT4gYWRkcmVzc2AgKGBVaW50VG9BZGRyZXNzTWFwYCkgYXJlCiAqIHN1cHBvcnRlZC4KICovCmxpYnJhcnkgRW51bWVyYWJsZU1hcCB7CiAgICAvLyBUbyBpbXBsZW1lbnQgdGhpcyBsaWJyYXJ5IGZvciBtdWx0aXBsZSB0eXBlcyB3aXRoIGFzIGxpdHRsZSBjb2RlCiAgICAvLyByZXBldGl0aW9uIGFzIHBvc3NpYmxlLCB3ZSB3cml0ZSBpdCBpbiB0ZXJtcyBvZiBhIGdlbmVyaWMgTWFwIHR5cGUgd2l0aAogICAgLy8gYnl0ZXMzMiBrZXlzIGFuZCB2YWx1ZXMuCiAgICAvLyBUaGUgTWFwIGltcGxlbWVudGF0aW9uIHVzZXMgcHJpdmF0ZSBmdW5jdGlvbnMsIGFuZCB1c2VyLWZhY2luZwogICAgLy8gaW1wbGVtZW50YXRpb25zIChzdWNoIGFzIFVpbnQyNTZUb0FkZHJlc3NNYXApIGFyZSBqdXN0IHdyYXBwZXJzIGFyb3VuZAogICAgLy8gdGhlIHVuZGVybHlpbmcgTWFwLgogICAgLy8gVGhpcyBtZWFucyB0aGF0IHdlIGNhbiBvbmx5IGNyZWF0ZSBuZXcgRW51bWVyYWJsZU1hcHMgZm9yIHR5cGVzIHRoYXQgZml0CiAgICAvLyBpbiBieXRlczMyLgoKICAgIHN0cnVjdCBNYXBFbnRyeSB7CiAgICAgICAgYnl0ZXMzMiBfa2V5OwogICAgICAgIGJ5dGVzMzIgX3ZhbHVlOwogICAgfQoKICAgIHN0cnVjdCBNYXAgewogICAgICAgIC8vIFN0b3JhZ2Ugb2YgbWFwIGtleXMgYW5kIHZhbHVlcwogICAgICAgIE1hcEVudHJ5W10gX2VudHJpZXM7CgogICAgICAgIC8vIFBvc2l0aW9uIG9mIHRoZSBlbnRyeSBkZWZpbmVkIGJ5IGEga2V5IGluIHRoZSBgZW50cmllc2AgYXJyYXksIHBsdXMgMQogICAgICAgIC8vIGJlY2F1c2UgaW5kZXggMCBtZWFucyBhIGtleSBpcyBub3QgaW4gdGhlIG1hcC4KICAgICAgICBtYXBwaW5nIChieXRlczMyID0+IHVpbnQyNTYpIF9pbmRleGVzOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBBZGRzIGEga2V5LXZhbHVlIHBhaXIgdG8gYSBtYXAsIG9yIHVwZGF0ZXMgdGhlIHZhbHVlIGZvciBhbiBleGlzdGluZwogICAgICoga2V5LiBPKDEpLgogICAgICoKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUga2V5IHdhcyBhZGRlZCB0byB0aGUgbWFwLCB0aGF0IGlzIGlmIGl0IHdhcyBub3QKICAgICAqIGFscmVhZHkgcHJlc2VudC4KICAgICAqLwogICAgZnVuY3Rpb24gX3NldChNYXAgc3RvcmFnZSBtYXAsIGJ5dGVzMzIga2V5LCBieXRlczMyIHZhbHVlKSBwcml2YXRlIHJldHVybnMgKGJvb2wpIHsKICAgICAgICAvLyBXZSByZWFkIGFuZCBzdG9yZSB0aGUga2V5J3MgaW5kZXggdG8gcHJldmVudCBtdWx0aXBsZSByZWFkcyBmcm9tIHRoZSBzYW1lIHN0b3JhZ2Ugc2xvdAogICAgICAgIHVpbnQyNTYga2V5SW5kZXggPSBtYXAuX2luZGV4ZXNba2V5XTsKCiAgICAgICAgaWYgKGtleUluZGV4ID09IDApIHsgLy8gRXF1aXZhbGVudCB0byAhY29udGFpbnMobWFwLCBrZXkpCiAgICAgICAgICAgIG1hcC5fZW50cmllcy5wdXNoKE1hcEVudHJ5KHsgX2tleToga2V5LCBfdmFsdWU6IHZhbHVlIH0pKTsKICAgICAgICAgICAgLy8gVGhlIGVudHJ5IGlzIHN0b3JlZCBhdCBsZW5ndGgtMSwgYnV0IHdlIGFkZCAxIHRvIGFsbCBpbmRleGVzCiAgICAgICAgICAgIC8vIGFuZCB1c2UgMCBhcyBhIHNlbnRpbmVsIHZhbHVlCiAgICAgICAgICAgIG1hcC5faW5kZXhlc1trZXldID0gbWFwLl9lbnRyaWVzLmxlbmd0aDsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbWFwLl9lbnRyaWVzW2tleUluZGV4IC0gMV0uX3ZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJlbW92ZXMgYSBrZXktdmFsdWUgcGFpciBmcm9tIGEgbWFwLiBPKDEpLgogICAgICoKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUga2V5IHdhcyByZW1vdmVkIGZyb20gdGhlIG1hcCwgdGhhdCBpcyBpZiBpdCB3YXMgcHJlc2VudC4KICAgICAqLwogICAgZnVuY3Rpb24gX3JlbW92ZShNYXAgc3RvcmFnZSBtYXAsIGJ5dGVzMzIga2V5KSBwcml2YXRlIHJldHVybnMgKGJvb2wpIHsKICAgICAgICAvLyBXZSByZWFkIGFuZCBzdG9yZSB0aGUga2V5J3MgaW5kZXggdG8gcHJldmVudCBtdWx0aXBsZSByZWFkcyBmcm9tIHRoZSBzYW1lIHN0b3JhZ2Ugc2xvdAogICAgICAgIHVpbnQyNTYga2V5SW5kZXggPSBtYXAuX2luZGV4ZXNba2V5XTsKCiAgICAgICAgaWYgKGtleUluZGV4ICE9IDApIHsgLy8gRXF1aXZhbGVudCB0byBjb250YWlucyhtYXAsIGtleSkKICAgICAgICAgICAgLy8gVG8gZGVsZXRlIGEga2V5LXZhbHVlIHBhaXIgZnJvbSB0aGUgX2VudHJpZXMgYXJyYXkgaW4gTygxKSwgd2Ugc3dhcCB0aGUgZW50cnkgdG8gZGVsZXRlIHdpdGggdGhlIGxhc3Qgb25lCiAgICAgICAgICAgIC8vIGluIHRoZSBhcnJheSwgYW5kIHRoZW4gcmVtb3ZlIHRoZSBsYXN0IGVudHJ5IChzb21ldGltZXMgY2FsbGVkIGFzICdzd2FwIGFuZCBwb3AnKS4KICAgICAgICAgICAgLy8gVGhpcyBtb2RpZmllcyB0aGUgb3JkZXIgb2YgdGhlIGFycmF5LCBhcyBub3RlZCBpbiB7YXR9LgoKICAgICAgICAgICAgdWludDI1NiB0b0RlbGV0ZUluZGV4ID0ga2V5SW5kZXggLSAxOwogICAgICAgICAgICB1aW50MjU2IGxhc3RJbmRleCA9IG1hcC5fZW50cmllcy5sZW5ndGggLSAxOwoKICAgICAgICAgICAgLy8gV2hlbiB0aGUgZW50cnkgdG8gZGVsZXRlIGlzIHRoZSBsYXN0IG9uZSwgdGhlIHN3YXAgb3BlcmF0aW9uIGlzIHVubmVjZXNzYXJ5LiBIb3dldmVyLCBzaW5jZSB0aGlzIG9jY3VycwogICAgICAgICAgICAvLyBzbyByYXJlbHksIHdlIHN0aWxsIGRvIHRoZSBzd2FwIGFueXdheSB0byBhdm9pZCB0aGUgZ2FzIGNvc3Qgb2YgYWRkaW5nIGFuICdpZicgc3RhdGVtZW50LgoKICAgICAgICAgICAgTWFwRW50cnkgc3RvcmFnZSBsYXN0RW50cnkgPSBtYXAuX2VudHJpZXNbbGFzdEluZGV4XTsKCiAgICAgICAgICAgIC8vIE1vdmUgdGhlIGxhc3QgZW50cnkgdG8gdGhlIGluZGV4IHdoZXJlIHRoZSBlbnRyeSB0byBkZWxldGUgaXMKICAgICAgICAgICAgbWFwLl9lbnRyaWVzW3RvRGVsZXRlSW5kZXhdID0gbGFzdEVudHJ5OwogICAgICAgICAgICAvLyBVcGRhdGUgdGhlIGluZGV4IGZvciB0aGUgbW92ZWQgZW50cnkKICAgICAgICAgICAgbWFwLl9pbmRleGVzW2xhc3RFbnRyeS5fa2V5XSA9IHRvRGVsZXRlSW5kZXggKyAxOyAvLyBBbGwgaW5kZXhlcyBhcmUgMS1iYXNlZAoKICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBzbG90IHdoZXJlIHRoZSBtb3ZlZCBlbnRyeSB3YXMgc3RvcmVkCiAgICAgICAgICAgIG1hcC5fZW50cmllcy5wb3AoKTsKCiAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgaW5kZXggZm9yIHRoZSBkZWxldGVkIHNsb3QKICAgICAgICAgICAgZGVsZXRlIG1hcC5faW5kZXhlc1trZXldOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0cnVlIGlmIHRoZSBrZXkgaXMgaW4gdGhlIG1hcC4gTygxKS4KICAgICAqLwogICAgZnVuY3Rpb24gX2NvbnRhaW5zKE1hcCBzdG9yYWdlIG1hcCwgYnl0ZXMzMiBrZXkpIHByaXZhdGUgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIG1hcC5faW5kZXhlc1trZXldICE9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG51bWJlciBvZiBrZXktdmFsdWUgcGFpcnMgaW4gdGhlIG1hcC4gTygxKS4KICAgICAqLwogICAgZnVuY3Rpb24gX2xlbmd0aChNYXAgc3RvcmFnZSBtYXApIHByaXZhdGUgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIG1hcC5fZW50cmllcy5sZW5ndGg7CiAgICB9CgogICAvKioKICAgICogQGRldiBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpciBzdG9yZWQgYXQgcG9zaXRpb24gYGluZGV4YCBpbiB0aGUgbWFwLiBPKDEpLgogICAgKgogICAgKiBOb3RlIHRoYXQgdGhlcmUgYXJlIG5vIGd1YXJhbnRlZXMgb24gdGhlIG9yZGVyaW5nIG9mIGVudHJpZXMgaW5zaWRlIHRoZQogICAgKiBhcnJheSwgYW5kIGl0IG1heSBjaGFuZ2Ugd2hlbiBtb3JlIGVudHJpZXMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuCiAgICAqCiAgICAqIFJlcXVpcmVtZW50czoKICAgICoKICAgICogLSBgaW5kZXhgIG11c3QgYmUgc3RyaWN0bHkgbGVzcyB0aGFuIHtsZW5ndGh9LgogICAgKi8KICAgIGZ1bmN0aW9uIF9hdChNYXAgc3RvcmFnZSBtYXAsIHVpbnQyNTYgaW5kZXgpIHByaXZhdGUgdmlldyByZXR1cm5zIChieXRlczMyLCBieXRlczMyKSB7CiAgICAgICAgcmVxdWlyZShtYXAuX2VudHJpZXMubGVuZ3RoID4gaW5kZXgsICJFbnVtZXJhYmxlTWFwOiBpbmRleCBvdXQgb2YgYm91bmRzIik7CgogICAgICAgIE1hcEVudHJ5IHN0b3JhZ2UgZW50cnkgPSBtYXAuX2VudHJpZXNbaW5kZXhdOwogICAgICAgIHJldHVybiAoZW50cnkuX2tleSwgZW50cnkuX3ZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgVHJpZXMgdG8gcmV0dXJucyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGBrZXlgLiAgTygxKS4KICAgICAqIERvZXMgbm90IHJldmVydCBpZiBga2V5YCBpcyBub3QgaW4gdGhlIG1hcC4KICAgICAqLwogICAgZnVuY3Rpb24gX3RyeUdldChNYXAgc3RvcmFnZSBtYXAsIGJ5dGVzMzIga2V5KSBwcml2YXRlIHZpZXcgcmV0dXJucyAoYm9vbCwgYnl0ZXMzMikgewogICAgICAgIHVpbnQyNTYga2V5SW5kZXggPSBtYXAuX2luZGV4ZXNba2V5XTsKICAgICAgICBpZiAoa2V5SW5kZXggPT0gMCkgcmV0dXJuIChmYWxzZSwgMCk7IC8vIEVxdWl2YWxlbnQgdG8gY29udGFpbnMobWFwLCBrZXkpCiAgICAgICAgcmV0dXJuICh0cnVlLCBtYXAuX2VudHJpZXNba2V5SW5kZXggLSAxXS5fdmFsdWUpOyAvLyBBbGwgaW5kZXhlcyBhcmUgMS1iYXNlZAogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggYGtleWAuICBPKDEpLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIGBrZXlgIG11c3QgYmUgaW4gdGhlIG1hcC4KICAgICAqLwogICAgZnVuY3Rpb24gX2dldChNYXAgc3RvcmFnZSBtYXAsIGJ5dGVzMzIga2V5KSBwcml2YXRlIHZpZXcgcmV0dXJucyAoYnl0ZXMzMikgewogICAgICAgIHVpbnQyNTYga2V5SW5kZXggPSBtYXAuX2luZGV4ZXNba2V5XTsKICAgICAgICByZXF1aXJlKGtleUluZGV4ICE9IDAsICJFbnVtZXJhYmxlTWFwOiBub25leGlzdGVudCBrZXkiKTsgLy8gRXF1aXZhbGVudCB0byBjb250YWlucyhtYXAsIGtleSkKICAgICAgICByZXR1cm4gbWFwLl9lbnRyaWVzW2tleUluZGV4IC0gMV0uX3ZhbHVlOyAvLyBBbGwgaW5kZXhlcyBhcmUgMS1iYXNlZAogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTYW1lIGFzIHtfZ2V0fSwgd2l0aCBhIGN1c3RvbSBlcnJvciBtZXNzYWdlIHdoZW4gYGtleWAgaXMgbm90IGluIHRoZSBtYXAuCiAgICAgKgogICAgICogQ0FVVElPTjogVGhpcyBmdW5jdGlvbiBpcyBkZXByZWNhdGVkIGJlY2F1c2UgaXQgcmVxdWlyZXMgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHRoZSBlcnJvcgogICAgICogbWVzc2FnZSB1bm5lY2Vzc2FyaWx5LiBGb3IgY3VzdG9tIHJldmVydCByZWFzb25zIHVzZSB7X3RyeUdldH0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9nZXQoTWFwIHN0b3JhZ2UgbWFwLCBieXRlczMyIGtleSwgc3RyaW5nIG1lbW9yeSBlcnJvck1lc3NhZ2UpIHByaXZhdGUgdmlldyByZXR1cm5zIChieXRlczMyKSB7CiAgICAgICAgdWludDI1NiBrZXlJbmRleCA9IG1hcC5faW5kZXhlc1trZXldOwogICAgICAgIHJlcXVpcmUoa2V5SW5kZXggIT0gMCwgZXJyb3JNZXNzYWdlKTsgLy8gRXF1aXZhbGVudCB0byBjb250YWlucyhtYXAsIGtleSkKICAgICAgICByZXR1cm4gbWFwLl9lbnRyaWVzW2tleUluZGV4IC0gMV0uX3ZhbHVlOyAvLyBBbGwgaW5kZXhlcyBhcmUgMS1iYXNlZAogICAgfQoKICAgIC8vIFVpbnRUb0FkZHJlc3NNYXAKCiAgICBzdHJ1Y3QgVWludFRvQWRkcmVzc01hcCB7CiAgICAgICAgTWFwIF9pbm5lcjsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQWRkcyBhIGtleS12YWx1ZSBwYWlyIHRvIGEgbWFwLCBvciB1cGRhdGVzIHRoZSB2YWx1ZSBmb3IgYW4gZXhpc3RpbmcKICAgICAqIGtleS4gTygxKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGtleSB3YXMgYWRkZWQgdG8gdGhlIG1hcCwgdGhhdCBpcyBpZiBpdCB3YXMgbm90CiAgICAgKiBhbHJlYWR5IHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNldChVaW50VG9BZGRyZXNzTWFwIHN0b3JhZ2UgbWFwLCB1aW50MjU2IGtleSwgYWRkcmVzcyB2YWx1ZSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfc2V0KG1hcC5faW5uZXIsIGJ5dGVzMzIoa2V5KSwgYnl0ZXMzMih1aW50MjU2KHVpbnQxNjAodmFsdWUpKSkpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZW1vdmVzIGEgdmFsdWUgZnJvbSBhIHNldC4gTygxKS4KICAgICAqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGtleSB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBtYXAsIHRoYXQgaXMgaWYgaXQgd2FzIHByZXNlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJlbW92ZShVaW50VG9BZGRyZXNzTWFwIHN0b3JhZ2UgbWFwLCB1aW50MjU2IGtleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfcmVtb3ZlKG1hcC5faW5uZXIsIGJ5dGVzMzIoa2V5KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdHJ1ZSBpZiB0aGUga2V5IGlzIGluIHRoZSBtYXAuIE8oMSkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGNvbnRhaW5zKFVpbnRUb0FkZHJlc3NNYXAgc3RvcmFnZSBtYXAsIHVpbnQyNTYga2V5KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX2NvbnRhaW5zKG1hcC5faW5uZXIsIGJ5dGVzMzIoa2V5KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbWFwLiBPKDEpLgogICAgICovCiAgICBmdW5jdGlvbiBsZW5ndGgoVWludFRvQWRkcmVzc01hcCBzdG9yYWdlIG1hcCkgaW50ZXJuYWwgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9sZW5ndGgobWFwLl9pbm5lcik7CiAgICB9CgogICAvKioKICAgICogQGRldiBSZXR1cm5zIHRoZSBlbGVtZW50IHN0b3JlZCBhdCBwb3NpdGlvbiBgaW5kZXhgIGluIHRoZSBzZXQuIE8oMSkuCiAgICAqIE5vdGUgdGhhdCB0aGVyZSBhcmUgbm8gZ3VhcmFudGVlcyBvbiB0aGUgb3JkZXJpbmcgb2YgdmFsdWVzIGluc2lkZSB0aGUKICAgICogYXJyYXksIGFuZCBpdCBtYXkgY2hhbmdlIHdoZW4gbW9yZSB2YWx1ZXMgYXJlIGFkZGVkIG9yIHJlbW92ZWQuCiAgICAqCiAgICAqIFJlcXVpcmVtZW50czoKICAgICoKICAgICogLSBgaW5kZXhgIG11c3QgYmUgc3RyaWN0bHkgbGVzcyB0aGFuIHtsZW5ndGh9LgogICAgKi8KICAgIGZ1bmN0aW9uIGF0KFVpbnRUb0FkZHJlc3NNYXAgc3RvcmFnZSBtYXAsIHVpbnQyNTYgaW5kZXgpIGludGVybmFsIHZpZXcgcmV0dXJucyAodWludDI1NiwgYWRkcmVzcykgewogICAgICAgIChieXRlczMyIGtleSwgYnl0ZXMzMiB2YWx1ZSkgPSBfYXQobWFwLl9pbm5lciwgaW5kZXgpOwogICAgICAgIHJldHVybiAodWludDI1NihrZXkpLCBhZGRyZXNzKHVpbnQxNjAodWludDI1Nih2YWx1ZSkpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFRyaWVzIHRvIHJldHVybnMgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBga2V5YC4gIE8oMSkuCiAgICAgKiBEb2VzIG5vdCByZXZlcnQgaWYgYGtleWAgaXMgbm90IGluIHRoZSBtYXAuCiAgICAgKgogICAgICogX0F2YWlsYWJsZSBzaW5jZSB2My40Ll8KICAgICAqLwogICAgZnVuY3Rpb24gdHJ5R2V0KFVpbnRUb0FkZHJlc3NNYXAgc3RvcmFnZSBtYXAsIHVpbnQyNTYga2V5KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wsIGFkZHJlc3MpIHsKICAgICAgICAoYm9vbCBzdWNjZXNzLCBieXRlczMyIHZhbHVlKSA9IF90cnlHZXQobWFwLl9pbm5lciwgYnl0ZXMzMihrZXkpKTsKICAgICAgICByZXR1cm4gKHN1Y2Nlc3MsIGFkZHJlc3ModWludDE2MCh1aW50MjU2KHZhbHVlKSkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGBrZXlgLiAgTygxKS4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBga2V5YCBtdXN0IGJlIGluIHRoZSBtYXAuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGdldChVaW50VG9BZGRyZXNzTWFwIHN0b3JhZ2UgbWFwLCB1aW50MjU2IGtleSkgaW50ZXJuYWwgdmlldyByZXR1cm5zIChhZGRyZXNzKSB7CiAgICAgICAgcmV0dXJuIGFkZHJlc3ModWludDE2MCh1aW50MjU2KF9nZXQobWFwLl9pbm5lciwgYnl0ZXMzMihrZXkpKSkpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2FtZSBhcyB7Z2V0fSwgd2l0aCBhIGN1c3RvbSBlcnJvciBtZXNzYWdlIHdoZW4gYGtleWAgaXMgbm90IGluIHRoZSBtYXAuCiAgICAgKgogICAgICogQ0FVVElPTjogVGhpcyBmdW5jdGlvbiBpcyBkZXByZWNhdGVkIGJlY2F1c2UgaXQgcmVxdWlyZXMgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHRoZSBlcnJvcgogICAgICogbWVzc2FnZSB1bm5lY2Vzc2FyaWx5LiBGb3IgY3VzdG9tIHJldmVydCByZWFzb25zIHVzZSB7dHJ5R2V0fS4KICAgICAqLwogICAgZnVuY3Rpb24gZ2V0KFVpbnRUb0FkZHJlc3NNYXAgc3RvcmFnZSBtYXAsIHVpbnQyNTYga2V5LCBzdHJpbmcgbWVtb3J5IGVycm9yTWVzc2FnZSkgaW50ZXJuYWwgdmlldyByZXR1cm5zIChhZGRyZXNzKSB7CiAgICAgICAgcmV0dXJuIGFkZHJlc3ModWludDE2MCh1aW50MjU2KF9nZXQobWFwLl9pbm5lciwgYnl0ZXMzMihrZXkpLCBlcnJvck1lc3NhZ2UpKSkpOwogICAgfQp9CgovLyBGaWxlOiBvcGVuemVwcGVsaW4tc29saWRpdHkvY29udHJhY3RzL3V0aWxzL1N0cmluZ3Muc29sCgovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCgpwcmFnbWEgc29saWRpdHkgPj0wLjYuMCA8MC44LjA7CgovKioKICogQGRldiBTdHJpbmcgb3BlcmF0aW9ucy4KICovCmxpYnJhcnkgU3RyaW5ncyB7CiAgICAvKioKICAgICAqIEBkZXYgQ29udmVydHMgYSBgdWludDI1NmAgdG8gaXRzIEFTQ0lJIGBzdHJpbmdgIHJlcHJlc2VudGF0aW9uLgogICAgICovCiAgICBmdW5jdGlvbiB0b1N0cmluZyh1aW50MjU2IHZhbHVlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICAvLyBJbnNwaXJlZCBieSBPcmFjbGl6ZUFQSSdzIGltcGxlbWVudGF0aW9uIC0gTUlUIGxpY2VuY2UKICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vb3JhY2xpemUvZXRoZXJldW0tYXBpL2Jsb2IvYjQyMTQ2YjA2M2M3ZDZlZTEzNTg4NDZjMTk4MjQ2MjM5ZTkzNjBlOC9vcmFjbGl6ZUFQSV8wLjQuMjUuc29sCgogICAgICAgIGlmICh2YWx1ZSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAiMCI7CiAgICAgICAgfQogICAgICAgIHVpbnQyNTYgdGVtcCA9IHZhbHVlOwogICAgICAgIHVpbnQyNTYgZGlnaXRzOwogICAgICAgIHdoaWxlICh0ZW1wICE9IDApIHsKICAgICAgICAgICAgZGlnaXRzKys7CiAgICAgICAgICAgIHRlbXAgLz0gMTA7CiAgICAgICAgfQogICAgICAgIGJ5dGVzIG1lbW9yeSBidWZmZXIgPSBuZXcgYnl0ZXMoZGlnaXRzKTsKICAgICAgICB1aW50MjU2IGluZGV4ID0gZGlnaXRzIC0gMTsKICAgICAgICB0ZW1wID0gdmFsdWU7CiAgICAgICAgd2hpbGUgKHRlbXAgIT0gMCkgewogICAgICAgICAgICBidWZmZXJbaW5kZXgtLV0gPSBieXRlczEodWludDgoNDggKyB0ZW1wICUgMTApKTsKICAgICAgICAgICAgdGVtcCAvPSAxMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZyhidWZmZXIpOwogICAgfQp9CgovLyBGaWxlOiBvcGVuemVwcGVsaW4tc29saWRpdHkvY29udHJhY3RzL3Rva2VuL0VSQzcyMS9FUkM3MjEuc29sCgovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCgpwcmFnbWEgc29saWRpdHkgPj0wLjYuMCA8MC44LjA7CgoKCgoKCgoKCgoKCi8qKgogKiBAdGl0bGUgRVJDNzIxIE5vbi1GdW5naWJsZSBUb2tlbiBTdGFuZGFyZCBiYXNpYyBpbXBsZW1lbnRhdGlvbgogKiBAZGV2IHNlZSBodHRwczovL2VpcHMuZXRoZXJldW0ub3JnL0VJUFMvZWlwLTcyMQogKi8KY29udHJhY3QgRVJDNzIxIGlzIENvbnRleHQsIEVSQzE2NSwgSUVSQzcyMSwgSUVSQzcyMU1ldGFkYXRhLCBJRVJDNzIxRW51bWVyYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CiAgICB1c2luZyBFbnVtZXJhYmxlU2V0IGZvciBFbnVtZXJhYmxlU2V0LlVpbnRTZXQ7CiAgICB1c2luZyBFbnVtZXJhYmxlTWFwIGZvciBFbnVtZXJhYmxlTWFwLlVpbnRUb0FkZHJlc3NNYXA7CiAgICB1c2luZyBTdHJpbmdzIGZvciB1aW50MjU2OwoKICAgIC8vIEVxdWFscyB0byBgYnl0ZXM0KGtlY2NhazI1Nigib25FUkM3MjFSZWNlaXZlZChhZGRyZXNzLGFkZHJlc3MsdWludDI1NixieXRlcykiKSlgCiAgICAvLyB3aGljaCBjYW4gYmUgYWxzbyBvYnRhaW5lZCBhcyBgSUVSQzcyMVJlY2VpdmVyKDApLm9uRVJDNzIxUmVjZWl2ZWQuc2VsZWN0b3JgCiAgICBieXRlczQgcHJpdmF0ZSBjb25zdGFudCBfRVJDNzIxX1JFQ0VJVkVEID0gMHgxNTBiN2EwMjsKCiAgICAvLyBNYXBwaW5nIGZyb20gaG9sZGVyIGFkZHJlc3MgdG8gdGhlaXIgKGVudW1lcmFibGUpIHNldCBvZiBvd25lZCB0b2tlbnMKICAgIG1hcHBpbmcgKGFkZHJlc3MgPT4gRW51bWVyYWJsZVNldC5VaW50U2V0KSBwcml2YXRlIF9ob2xkZXJUb2tlbnM7CgogICAgLy8gRW51bWVyYWJsZSBtYXBwaW5nIGZyb20gdG9rZW4gaWRzIHRvIHRoZWlyIG93bmVycwogICAgRW51bWVyYWJsZU1hcC5VaW50VG9BZGRyZXNzTWFwIHByaXZhdGUgX3Rva2VuT3duZXJzOwoKICAgIC8vIE1hcHBpbmcgZnJvbSB0b2tlbiBJRCB0byBhcHByb3ZlZCBhZGRyZXNzCiAgICBtYXBwaW5nICh1aW50MjU2ID0+IGFkZHJlc3MpIHByaXZhdGUgX3Rva2VuQXBwcm92YWxzOwoKICAgIC8vIE1hcHBpbmcgZnJvbSBvd25lciB0byBvcGVyYXRvciBhcHByb3ZhbHMKICAgIG1hcHBpbmcgKGFkZHJlc3MgPT4gbWFwcGluZyAoYWRkcmVzcyA9PiBib29sKSkgcHJpdmF0ZSBfb3BlcmF0b3JBcHByb3ZhbHM7CgogICAgLy8gVG9rZW4gbmFtZQogICAgc3RyaW5nIHByaXZhdGUgX25hbWU7CgogICAgLy8gVG9rZW4gc3ltYm9sCiAgICBzdHJpbmcgcHJpdmF0ZSBfc3ltYm9sOwoKICAgIC8vIE9wdGlvbmFsIG1hcHBpbmcgZm9yIHRva2VuIFVSSXMKICAgIG1hcHBpbmcgKHVpbnQyNTYgPT4gc3RyaW5nKSBwcml2YXRlIF90b2tlblVSSXM7CgogICAgLy8gQmFzZSBVUkkKICAgIHN0cmluZyBwcml2YXRlIF9iYXNlVVJJOwoKICAgIC8qCiAgICAgKiAgICAgYnl0ZXM0KGtlY2NhazI1NignYmFsYW5jZU9mKGFkZHJlc3MpJykpID09IDB4NzBhMDgyMzEKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdvd25lck9mKHVpbnQyNTYpJykpID09IDB4NjM1MjIxMWUKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknKSkgPT0gMHgwOTVlYTdiMwogICAgICogICAgIGJ5dGVzNChrZWNjYWsyNTYoJ2dldEFwcHJvdmVkKHVpbnQyNTYpJykpID09IDB4MDgxODEyZmMKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzLGJvb2wpJykpID09IDB4YTIyY2I0NjUKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdpc0FwcHJvdmVkRm9yQWxsKGFkZHJlc3MsYWRkcmVzcyknKSkgPT0gMHhlOTg1ZTljNQogICAgICogICAgIGJ5dGVzNChrZWNjYWsyNTYoJ3RyYW5zZmVyRnJvbShhZGRyZXNzLGFkZHJlc3MsdWludDI1NiknKSkgPT0gMHgyM2I4NzJkZAogICAgICogICAgIGJ5dGVzNChrZWNjYWsyNTYoJ3NhZmVUcmFuc2ZlckZyb20oYWRkcmVzcyxhZGRyZXNzLHVpbnQyNTYpJykpID09IDB4NDI4NDJlMGUKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdzYWZlVHJhbnNmZXJGcm9tKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKScpKSA9PSAweGI4OGQ0ZmRlCiAgICAgKgogICAgICogICAgID0+IDB4NzBhMDgyMzEgXiAweDYzNTIyMTFlIF4gMHgwOTVlYTdiMyBeIDB4MDgxODEyZmMgXgogICAgICogICAgICAgIDB4YTIyY2I0NjUgXiAweGU5ODVlOWM1IF4gMHgyM2I4NzJkZCBeIDB4NDI4NDJlMGUgXiAweGI4OGQ0ZmRlID09IDB4ODBhYzU4Y2QKICAgICAqLwogICAgYnl0ZXM0IHByaXZhdGUgY29uc3RhbnQgX0lOVEVSRkFDRV9JRF9FUkM3MjEgPSAweDgwYWM1OGNkOwoKICAgIC8qCiAgICAgKiAgICAgYnl0ZXM0KGtlY2NhazI1NignbmFtZSgpJykpID09IDB4MDZmZGRlMDMKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCdzeW1ib2woKScpKSA9PSAweDk1ZDg5YjQxCiAgICAgKiAgICAgYnl0ZXM0KGtlY2NhazI1NigndG9rZW5VUkkodWludDI1NiknKSkgPT0gMHhjODdiNTZkZAogICAgICoKICAgICAqICAgICA9PiAweDA2ZmRkZTAzIF4gMHg5NWQ4OWI0MSBeIDB4Yzg3YjU2ZGQgPT0gMHg1YjVlMTM5ZgogICAgICovCiAgICBieXRlczQgcHJpdmF0ZSBjb25zdGFudCBfSU5URVJGQUNFX0lEX0VSQzcyMV9NRVRBREFUQSA9IDB4NWI1ZTEzOWY7CgogICAgLyoKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCd0b3RhbFN1cHBseSgpJykpID09IDB4MTgxNjBkZGQKICAgICAqICAgICBieXRlczQoa2VjY2FrMjU2KCd0b2tlbk9mT3duZXJCeUluZGV4KGFkZHJlc3MsdWludDI1NiknKSkgPT0gMHgyZjc0NWM1OQogICAgICogICAgIGJ5dGVzNChrZWNjYWsyNTYoJ3Rva2VuQnlJbmRleCh1aW50MjU2KScpKSA9PSAweDRmNmNjY2U3CiAgICAgKgogICAgICogICAgID0+IDB4MTgxNjBkZGQgXiAweDJmNzQ1YzU5IF4gMHg0ZjZjY2NlNyA9PSAweDc4MGU5ZDYzCiAgICAgKi8KICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9JTlRFUkZBQ0VfSURfRVJDNzIxX0VOVU1FUkFCTEUgPSAweDc4MGU5ZDYzOwoKICAgIC8qKgogICAgICogQGRldiBJbml0aWFsaXplcyB0aGUgY29udHJhY3QgYnkgc2V0dGluZyBhIGBuYW1lYCBhbmQgYSBgc3ltYm9sYCB0byB0aGUgdG9rZW4gY29sbGVjdGlvbi4KICAgICAqLwogICAgY29uc3RydWN0b3IgKHN0cmluZyBtZW1vcnkgbmFtZV8sIHN0cmluZyBtZW1vcnkgc3ltYm9sXykgcHVibGljIHsKICAgICAgICBfbmFtZSA9IG5hbWVfOwogICAgICAgIF9zeW1ib2wgPSBzeW1ib2xfOwoKICAgICAgICAvLyByZWdpc3RlciB0aGUgc3VwcG9ydGVkIGludGVyZmFjZXMgdG8gY29uZm9ybSB0byBFUkM3MjEgdmlhIEVSQzE2NQogICAgICAgIF9yZWdpc3RlckludGVyZmFjZShfSU5URVJGQUNFX0lEX0VSQzcyMSk7CiAgICAgICAgX3JlZ2lzdGVySW50ZXJmYWNlKF9JTlRFUkZBQ0VfSURfRVJDNzIxX01FVEFEQVRBKTsKICAgICAgICBfcmVnaXN0ZXJJbnRlcmZhY2UoX0lOVEVSRkFDRV9JRF9FUkM3MjFfRU5VTUVSQUJMRSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzcyMS1iYWxhbmNlT2Z9LgogICAgICovCiAgICBmdW5jdGlvbiBiYWxhbmNlT2YoYWRkcmVzcyBvd25lcikgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShvd25lciAhPSBhZGRyZXNzKDApLCAiRVJDNzIxOiBiYWxhbmNlIHF1ZXJ5IGZvciB0aGUgemVybyBhZGRyZXNzIik7CiAgICAgICAgcmV0dXJuIF9ob2xkZXJUb2tlbnNbb3duZXJdLmxlbmd0aCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZWUge0lFUkM3MjEtb3duZXJPZn0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIG93bmVyT2YodWludDI1NiB0b2tlbklkKSBwdWJsaWMgdmlldyB2aXJ0dWFsIG92ZXJyaWRlIHJldHVybnMgKGFkZHJlc3MpIHsKICAgICAgICByZXR1cm4gX3Rva2VuT3duZXJzLmdldCh0b2tlbklkLCAiRVJDNzIxOiBvd25lciBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgdG9rZW4iKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2VlIHtJRVJDNzIxTWV0YWRhdGEtbmFtZX0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIG5hbWUoKSBwdWJsaWMgdmlldyB2aXJ0dWFsIG92ZXJyaWRlIHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX25hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzcyMU1ldGFkYXRhLXN5bWJvbH0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN5bWJvbCgpIHB1YmxpYyB2aWV3IHZpcnR1YWwgb3ZlcnJpZGUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSkgewogICAgICAgIHJldHVybiBfc3ltYm9sOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZWUge0lFUkM3MjFNZXRhZGF0YS10b2tlblVSSX0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRva2VuVVJJKHVpbnQyNTYgdG9rZW5JZCkgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKHRva2VuSWQpLCAiRVJDNzIxTWV0YWRhdGE6IFVSSSBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgdG9rZW4iKTsKCiAgICAgICAgc3RyaW5nIG1lbW9yeSBfdG9rZW5VUkkgPSBfdG9rZW5VUklzW3Rva2VuSWRdOwogICAgICAgIHN0cmluZyBtZW1vcnkgYmFzZSA9IGJhc2VVUkkoKTsKCiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gYmFzZSBVUkksIHJldHVybiB0aGUgdG9rZW4gVVJJLgogICAgICAgIGlmIChieXRlcyhiYXNlKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm4gX3Rva2VuVVJJOwogICAgICAgIH0KICAgICAgICAvLyBJZiBib3RoIGFyZSBzZXQsIGNvbmNhdGVuYXRlIHRoZSBiYXNlVVJJIGFuZCB0b2tlblVSSSAodmlhIGFiaS5lbmNvZGVQYWNrZWQpLgogICAgICAgIGlmIChieXRlcyhfdG9rZW5VUkkpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmluZyhhYmkuZW5jb2RlUGFja2VkKGJhc2UsIF90b2tlblVSSSkpOwogICAgICAgIH0KICAgICAgICAvLyBJZiB0aGVyZSBpcyBhIGJhc2VVUkkgYnV0IG5vIHRva2VuVVJJLCBjb25jYXRlbmF0ZSB0aGUgdG9rZW5JRCB0byB0aGUgYmFzZVVSSS4KICAgICAgICByZXR1cm4gc3RyaW5nKGFiaS5lbmNvZGVQYWNrZWQoYmFzZSwgdG9rZW5JZC50b1N0cmluZygpKSk7CiAgICB9CgogICAgLyoqCiAgICAqIEBkZXYgUmV0dXJucyB0aGUgYmFzZSBVUkkgc2V0IHZpYSB7X3NldEJhc2VVUkl9LiBUaGlzIHdpbGwgYmUKICAgICogYXV0b21hdGljYWxseSBhZGRlZCBhcyBhIHByZWZpeCBpbiB7dG9rZW5VUkl9IHRvIGVhY2ggdG9rZW4ncyBVUkksIG9yCiAgICAqIHRvIHRoZSB0b2tlbiBJRCBpZiBubyBzcGVjaWZpYyBVUkkgaXMgc2V0IGZvciB0aGF0IHRva2VuIElELgogICAgKi8KICAgIGZ1bmN0aW9uIGJhc2VVUkkoKSBwdWJsaWMgdmlldyB2aXJ0dWFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX2Jhc2VVUkk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzcyMUVudW1lcmFibGUtdG9rZW5PZk93bmVyQnlJbmRleH0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRva2VuT2ZPd25lckJ5SW5kZXgoYWRkcmVzcyBvd25lciwgdWludDI1NiBpbmRleCkgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9ob2xkZXJUb2tlbnNbb3duZXJdLmF0KGluZGV4KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2VlIHtJRVJDNzIxRW51bWVyYWJsZS10b3RhbFN1cHBseX0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRvdGFsU3VwcGx5KCkgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgLy8gX3Rva2VuT3duZXJzIGFyZSBpbmRleGVkIGJ5IHRva2VuSWRzLCBzbyAubGVuZ3RoKCkgcmV0dXJucyB0aGUgbnVtYmVyIG9mIHRva2VuSWRzCiAgICAgICAgcmV0dXJuIF90b2tlbk93bmVycy5sZW5ndGgoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2VlIHtJRVJDNzIxRW51bWVyYWJsZS10b2tlbkJ5SW5kZXh9LgogICAgICovCiAgICBmdW5jdGlvbiB0b2tlbkJ5SW5kZXgodWludDI1NiBpbmRleCkgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgKHVpbnQyNTYgdG9rZW5JZCwgKSA9IF90b2tlbk93bmVycy5hdChpbmRleCk7CiAgICAgICAgcmV0dXJuIHRva2VuSWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzcyMS1hcHByb3ZlfS4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIHB1YmxpYyB2aXJ0dWFsIG92ZXJyaWRlIHsKICAgICAgICBhZGRyZXNzIG93bmVyID0gRVJDNzIxLm93bmVyT2YodG9rZW5JZCk7CiAgICAgICAgcmVxdWlyZSh0byAhPSBvd25lciwgIkVSQzcyMTogYXBwcm92YWwgdG8gY3VycmVudCBvd25lciIpOwoKICAgICAgICByZXF1aXJlKF9tc2dTZW5kZXIoKSA9PSBvd25lciB8fCBFUkM3MjEuaXNBcHByb3ZlZEZvckFsbChvd25lciwgX21zZ1NlbmRlcigpKSwKICAgICAgICAgICAgIkVSQzcyMTogYXBwcm92ZSBjYWxsZXIgaXMgbm90IG93bmVyIG5vciBhcHByb3ZlZCBmb3IgYWxsIgogICAgICAgICk7CgogICAgICAgIF9hcHByb3ZlKHRvLCB0b2tlbklkKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2VlIHtJRVJDNzIxLWdldEFwcHJvdmVkfS4KICAgICAqLwogICAgZnVuY3Rpb24gZ2V0QXBwcm92ZWQodWludDI1NiB0b2tlbklkKSBwdWJsaWMgdmlldyB2aXJ0dWFsIG92ZXJyaWRlIHJldHVybnMgKGFkZHJlc3MpIHsKICAgICAgICByZXF1aXJlKF9leGlzdHModG9rZW5JZCksICJFUkM3MjE6IGFwcHJvdmVkIHF1ZXJ5IGZvciBub25leGlzdGVudCB0b2tlbiIpOwoKICAgICAgICByZXR1cm4gX3Rva2VuQXBwcm92YWxzW3Rva2VuSWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZWUge0lFUkM3MjEtc2V0QXBwcm92YWxGb3JBbGx9LgogICAgICovCiAgICBmdW5jdGlvbiBzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzIG9wZXJhdG9yLCBib29sIGFwcHJvdmVkKSBwdWJsaWMgdmlydHVhbCBvdmVycmlkZSB7CiAgICAgICAgcmVxdWlyZShvcGVyYXRvciAhPSBfbXNnU2VuZGVyKCksICJFUkM3MjE6IGFwcHJvdmUgdG8gY2FsbGVyIik7CgogICAgICAgIF9vcGVyYXRvckFwcHJvdmFsc1tfbXNnU2VuZGVyKCldW29wZXJhdG9yXSA9IGFwcHJvdmVkOwogICAgICAgIGVtaXQgQXBwcm92YWxGb3JBbGwoX21zZ1NlbmRlcigpLCBvcGVyYXRvciwgYXBwcm92ZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZWUge0lFUkM3MjEtaXNBcHByb3ZlZEZvckFsbH0uCiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQXBwcm92ZWRGb3JBbGwoYWRkcmVzcyBvd25lciwgYWRkcmVzcyBvcGVyYXRvcikgcHVibGljIHZpZXcgdmlydHVhbCBvdmVycmlkZSByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9vcGVyYXRvckFwcHJvdmFsc1tvd25lcl1bb3BlcmF0b3JdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZWUge0lFUkM3MjEtdHJhbnNmZXJGcm9tfS4KICAgICAqLwogICAgZnVuY3Rpb24gdHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkKSBwdWJsaWMgdmlydHVhbCBvdmVycmlkZSB7CiAgICAgICAgLy9zb2xoaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1saW5lLWxlbmd0aAogICAgICAgIHJlcXVpcmUoX2lzQXBwcm92ZWRPck93bmVyKF9tc2dTZW5kZXIoKSwgdG9rZW5JZCksICJFUkM3MjE6IHRyYW5zZmVyIGNhbGxlciBpcyBub3Qgb3duZXIgbm9yIGFwcHJvdmVkIik7CgogICAgICAgIF90cmFuc2Zlcihmcm9tLCB0bywgdG9rZW5JZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlZSB7SUVSQzcyMS1zYWZlVHJhbnNmZXJGcm9tfS4KICAgICAqLwogICAgZnVuY3Rpb24gc2FmZVRyYW5zZmVyRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdG9rZW5JZCkgcHVibGljIHZpcnR1YWwgb3ZlcnJpZGUgewogICAgICAgIHNhZmVUcmFuc2ZlckZyb20oZnJvbSwgdG8sIHRva2VuSWQsICIiKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2VlIHtJRVJDNzIxLXNhZmVUcmFuc2ZlckZyb219LgogICAgICovCiAgICBmdW5jdGlvbiBzYWZlVHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkLCBieXRlcyBtZW1vcnkgX2RhdGEpIHB1YmxpYyB2aXJ0dWFsIG92ZXJyaWRlIHsKICAgICAgICByZXF1aXJlKF9pc0FwcHJvdmVkT3JPd25lcihfbXNnU2VuZGVyKCksIHRva2VuSWQpLCAiRVJDNzIxOiB0cmFuc2ZlciBjYWxsZXIgaXMgbm90IG93bmVyIG5vciBhcHByb3ZlZCIpOwogICAgICAgIF9zYWZlVHJhbnNmZXIoZnJvbSwgdG8sIHRva2VuSWQsIF9kYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgU2FmZWx5IHRyYW5zZmVycyBgdG9rZW5JZGAgdG9rZW4gZnJvbSBgZnJvbWAgdG8gYHRvYCwgY2hlY2tpbmcgZmlyc3QgdGhhdCBjb250cmFjdCByZWNpcGllbnRzCiAgICAgKiBhcmUgYXdhcmUgb2YgdGhlIEVSQzcyMSBwcm90b2NvbCB0byBwcmV2ZW50IHRva2VucyBmcm9tIGJlaW5nIGZvcmV2ZXIgbG9ja2VkLgogICAgICoKICAgICAqIGBfZGF0YWAgaXMgYWRkaXRpb25hbCBkYXRhLCBpdCBoYXMgbm8gc3BlY2lmaWVkIGZvcm1hdCBhbmQgaXQgaXMgc2VudCBpbiBjYWxsIHRvIGB0b2AuCiAgICAgKgogICAgICogVGhpcyBpbnRlcm5hbCBmdW5jdGlvbiBpcyBlcXVpdmFsZW50IHRvIHtzYWZlVHJhbnNmZXJGcm9tfSwgYW5kIGNhbiBiZSB1c2VkIHRvIGUuZy4KICAgICAqIGltcGxlbWVudCBhbHRlcm5hdGl2ZSBtZWNoYW5pc21zIHRvIHBlcmZvcm0gdG9rZW4gdHJhbnNmZXIsIHN1Y2ggYXMgc2lnbmF0dXJlLWJhc2VkLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIGBmcm9tYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqIC0gYHRvYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqIC0gYHRva2VuSWRgIHRva2VuIG11c3QgZXhpc3QgYW5kIGJlIG93bmVkIGJ5IGBmcm9tYC4KICAgICAqIC0gSWYgYHRvYCByZWZlcnMgdG8gYSBzbWFydCBjb250cmFjdCwgaXQgbXVzdCBpbXBsZW1lbnQge0lFUkM3MjFSZWNlaXZlci1vbkVSQzcyMVJlY2VpdmVkfSwgd2hpY2ggaXMgY2FsbGVkIHVwb24gYSBzYWZlIHRyYW5zZmVyLgogICAgICoKICAgICAqIEVtaXRzIGEge1RyYW5zZmVyfSBldmVudC4KICAgICAqLwogICAgZnVuY3Rpb24gX3NhZmVUcmFuc2ZlcihhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdG9rZW5JZCwgYnl0ZXMgbWVtb3J5IF9kYXRhKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICBfdHJhbnNmZXIoZnJvbSwgdG8sIHRva2VuSWQpOwogICAgICAgIHJlcXVpcmUoX2NoZWNrT25FUkM3MjFSZWNlaXZlZChmcm9tLCB0bywgdG9rZW5JZCwgX2RhdGEpLCAiRVJDNzIxOiB0cmFuc2ZlciB0byBub24gRVJDNzIxUmVjZWl2ZXIgaW1wbGVtZW50ZXIiKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyB3aGV0aGVyIGB0b2tlbklkYCBleGlzdHMuCiAgICAgKgogICAgICogVG9rZW5zIGNhbiBiZSBtYW5hZ2VkIGJ5IHRoZWlyIG93bmVyIG9yIGFwcHJvdmVkIGFjY291bnRzIHZpYSB7YXBwcm92ZX0gb3Ige3NldEFwcHJvdmFsRm9yQWxsfS4KICAgICAqCiAgICAgKiBUb2tlbnMgc3RhcnQgZXhpc3Rpbmcgd2hlbiB0aGV5IGFyZSBtaW50ZWQgKGBfbWludGApLAogICAgICogYW5kIHN0b3AgZXhpc3Rpbmcgd2hlbiB0aGV5IGFyZSBidXJuZWQgKGBfYnVybmApLgogICAgICovCiAgICBmdW5jdGlvbiBfZXhpc3RzKHVpbnQyNTYgdG9rZW5JZCkgaW50ZXJuYWwgdmlldyB2aXJ0dWFsIHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX3Rva2VuT3duZXJzLmNvbnRhaW5zKHRva2VuSWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHdoZXRoZXIgYHNwZW5kZXJgIGlzIGFsbG93ZWQgdG8gbWFuYWdlIGB0b2tlbklkYC4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBgdG9rZW5JZGAgbXVzdCBleGlzdC4KICAgICAqLwogICAgZnVuY3Rpb24gX2lzQXBwcm92ZWRPck93bmVyKGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB0b2tlbklkKSBpbnRlcm5hbCB2aWV3IHZpcnR1YWwgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoX2V4aXN0cyh0b2tlbklkKSwgIkVSQzcyMTogb3BlcmF0b3IgcXVlcnkgZm9yIG5vbmV4aXN0ZW50IHRva2VuIik7CiAgICAgICAgYWRkcmVzcyBvd25lciA9IEVSQzcyMS5vd25lck9mKHRva2VuSWQpOwogICAgICAgIHJldHVybiAoc3BlbmRlciA9PSBvd25lciB8fCBnZXRBcHByb3ZlZCh0b2tlbklkKSA9PSBzcGVuZGVyIHx8IEVSQzcyMS5pc0FwcHJvdmVkRm9yQWxsKG93bmVyLCBzcGVuZGVyKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNhZmVseSBtaW50cyBgdG9rZW5JZGAgYW5kIHRyYW5zZmVycyBpdCB0byBgdG9gLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICBkKgogICAgICogLSBgdG9rZW5JZGAgbXVzdCBub3QgZXhpc3QuCiAgICAgKiAtIElmIGB0b2AgcmVmZXJzIHRvIGEgc21hcnQgY29udHJhY3QsIGl0IG11c3QgaW1wbGVtZW50IHtJRVJDNzIxUmVjZWl2ZXItb25FUkM3MjFSZWNlaXZlZH0sIHdoaWNoIGlzIGNhbGxlZCB1cG9uIGEgc2FmZSB0cmFuc2Zlci4KICAgICAqCiAgICAgKiBFbWl0cyBhIHtUcmFuc2Zlcn0gZXZlbnQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9zYWZlTWludChhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIGludGVybmFsIHZpcnR1YWwgewogICAgICAgIF9zYWZlTWludCh0bywgdG9rZW5JZCwgIiIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTYW1lIGFzIHt4cmVmLUVSQzcyMS1fc2FmZU1pbnQtYWRkcmVzcy11aW50MjU2LX1bYF9zYWZlTWludGBdLCB3aXRoIGFuIGFkZGl0aW9uYWwgYGRhdGFgIHBhcmFtZXRlciB3aGljaCBpcwogICAgICogZm9yd2FyZGVkIGluIHtJRVJDNzIxUmVjZWl2ZXItb25FUkM3MjFSZWNlaXZlZH0gdG8gY29udHJhY3QgcmVjaXBpZW50cy4KICAgICAqLwogICAgZnVuY3Rpb24gX3NhZmVNaW50KGFkZHJlc3MgdG8sIHVpbnQyNTYgdG9rZW5JZCwgYnl0ZXMgbWVtb3J5IF9kYXRhKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICBfbWludCh0bywgdG9rZW5JZCk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkVSQzcyMVJlY2VpdmVkKGFkZHJlc3MoMCksIHRvLCB0b2tlbklkLCBfZGF0YSksICJFUkM3MjE6IHRyYW5zZmVyIHRvIG5vbiBFUkM3MjFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNaW50cyBgdG9rZW5JZGAgYW5kIHRyYW5zZmVycyBpdCB0byBgdG9gLgogICAgICoKICAgICAqIFdBUk5JTkc6IFVzYWdlIG9mIHRoaXMgbWV0aG9kIGlzIGRpc2NvdXJhZ2VkLCB1c2Uge19zYWZlTWludH0gd2hlbmV2ZXIgcG9zc2libGUKICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBgdG9rZW5JZGAgbXVzdCBub3QgZXhpc3QuCiAgICAgKiAtIGB0b2AgY2Fubm90IGJlIHRoZSB6ZXJvIGFkZHJlc3MuCiAgICAgKgogICAgICogRW1pdHMgYSB7VHJhbnNmZXJ9IGV2ZW50LgogICAgICovCiAgICBmdW5jdGlvbiBfbWludChhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIGludGVybmFsIHZpcnR1YWwgewogICAgICAgIHJlcXVpcmUodG8gIT0gYWRkcmVzcygwKSwgIkVSQzcyMTogbWludCB0byB0aGUgemVybyBhZGRyZXNzIik7CiAgICAgICAgcmVxdWlyZSghX2V4aXN0cyh0b2tlbklkKSwgIkVSQzcyMTogdG9rZW4gYWxyZWFkeSBtaW50ZWQiKTsKCiAgICAgICAgX2JlZm9yZVRva2VuVHJhbnNmZXIoYWRkcmVzcygwKSwgdG8sIHRva2VuSWQpOwoKICAgICAgICBfaG9sZGVyVG9rZW5zW3RvXS5hZGQodG9rZW5JZCk7CgogICAgICAgIF90b2tlbk93bmVycy5zZXQodG9rZW5JZCwgdG8pOwoKICAgICAgICBlbWl0IFRyYW5zZmVyKGFkZHJlc3MoMCksIHRvLCB0b2tlbklkKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgRGVzdHJveXMgYHRva2VuSWRgLgogICAgICogVGhlIGFwcHJvdmFsIGlzIGNsZWFyZWQgd2hlbiB0aGUgdG9rZW4gaXMgYnVybmVkLgogICAgICoKICAgICAqIFJlcXVpcmVtZW50czoKICAgICAqCiAgICAgKiAtIGB0b2tlbklkYCBtdXN0IGV4aXN0LgogICAgICoKICAgICAqIEVtaXRzIGEge1RyYW5zZmVyfSBldmVudC4KICAgICAqLwogICAgZnVuY3Rpb24gX2J1cm4odWludDI1NiB0b2tlbklkKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICBhZGRyZXNzIG93bmVyID0gRVJDNzIxLm93bmVyT2YodG9rZW5JZCk7IC8vIGludGVybmFsIG93bmVyCgogICAgICAgIF9iZWZvcmVUb2tlblRyYW5zZmVyKG93bmVyLCBhZGRyZXNzKDApLCB0b2tlbklkKTsKCiAgICAgICAgLy8gQ2xlYXIgYXBwcm92YWxzCiAgICAgICAgX2FwcHJvdmUoYWRkcmVzcygwKSwgdG9rZW5JZCk7CgogICAgICAgIC8vIENsZWFyIG1ldGFkYXRhIChpZiBhbnkpCiAgICAgICAgaWYgKGJ5dGVzKF90b2tlblVSSXNbdG9rZW5JZF0pLmxlbmd0aCAhPSAwKSB7CiAgICAgICAgICAgIGRlbGV0ZSBfdG9rZW5VUklzW3Rva2VuSWRdOwogICAgICAgIH0KCiAgICAgICAgX2hvbGRlclRva2Vuc1tvd25lcl0ucmVtb3ZlKHRva2VuSWQpOwoKICAgICAgICBfdG9rZW5Pd25lcnMucmVtb3ZlKHRva2VuSWQpOwoKICAgICAgICBlbWl0IFRyYW5zZmVyKG93bmVyLCBhZGRyZXNzKDApLCB0b2tlbklkKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgVHJhbnNmZXJzIGB0b2tlbklkYCBmcm9tIGBmcm9tYCB0byBgdG9gLgogICAgICogIEFzIG9wcG9zZWQgdG8ge3RyYW5zZmVyRnJvbX0sIHRoaXMgaW1wb3NlcyBubyByZXN0cmljdGlvbnMgb24gbXNnLnNlbmRlci4KICAgICAqCiAgICAgKiBSZXF1aXJlbWVudHM6CiAgICAgKgogICAgICogLSBgdG9gIGNhbm5vdCBiZSB0aGUgemVybyBhZGRyZXNzLgogICAgICogLSBgdG9rZW5JZGAgdG9rZW4gbXVzdCBiZSBvd25lZCBieSBgZnJvbWAuCiAgICAgKgogICAgICogRW1pdHMgYSB7VHJhbnNmZXJ9IGV2ZW50LgogICAgICovCiAgICBmdW5jdGlvbiBfdHJhbnNmZXIoYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQpIGludGVybmFsIHZpcnR1YWwgewogICAgICAgIHJlcXVpcmUoRVJDNzIxLm93bmVyT2YodG9rZW5JZCkgPT0gZnJvbSwgIkVSQzcyMTogdHJhbnNmZXIgb2YgdG9rZW4gdGhhdCBpcyBub3Qgb3duIik7IC8vIGludGVybmFsIG93bmVyCiAgICAgICAgcmVxdWlyZSh0byAhPSBhZGRyZXNzKDApLCAiRVJDNzIxOiB0cmFuc2ZlciB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9iZWZvcmVUb2tlblRyYW5zZmVyKGZyb20sIHRvLCB0b2tlbklkKTsKCiAgICAgICAgLy8gQ2xlYXIgYXBwcm92YWxzIGZyb20gdGhlIHByZXZpb3VzIG93bmVyCiAgICAgICAgX2FwcHJvdmUoYWRkcmVzcygwKSwgdG9rZW5JZCk7CgogICAgICAgIF9ob2xkZXJUb2tlbnNbZnJvbV0ucmVtb3ZlKHRva2VuSWQpOwogICAgICAgIF9ob2xkZXJUb2tlbnNbdG9dLmFkZCh0b2tlbklkKTsKCiAgICAgICAgX3Rva2VuT3duZXJzLnNldCh0b2tlbklkLCB0byk7CgogICAgICAgIGVtaXQgVHJhbnNmZXIoZnJvbSwgdG8sIHRva2VuSWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZXRzIGBfdG9rZW5VUklgIGFzIHRoZSB0b2tlblVSSSBvZiBgdG9rZW5JZGAuCiAgICAgKgogICAgICogUmVxdWlyZW1lbnRzOgogICAgICoKICAgICAqIC0gYHRva2VuSWRgIG11c3QgZXhpc3QuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9zZXRUb2tlblVSSSh1aW50MjU2IHRva2VuSWQsIHN0cmluZyBtZW1vcnkgX3Rva2VuVVJJKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICByZXF1aXJlKF9leGlzdHModG9rZW5JZCksICJFUkM3MjFNZXRhZGF0YTogVVJJIHNldCBvZiBub25leGlzdGVudCB0b2tlbiIpOwogICAgICAgIF90b2tlblVSSXNbdG9rZW5JZF0gPSBfdG9rZW5VUkk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIHNldCB0aGUgYmFzZSBVUkkgZm9yIGFsbCB0b2tlbiBJRHMuIEl0IGlzCiAgICAgKiBhdXRvbWF0aWNhbGx5IGFkZGVkIGFzIGEgcHJlZml4IHRvIHRoZSB2YWx1ZSByZXR1cm5lZCBpbiB7dG9rZW5VUkl9LAogICAgICogb3IgdG8gdGhlIHRva2VuIElEIGlmIHt0b2tlblVSSX0gaXMgZW1wdHkuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9zZXRCYXNlVVJJKHN0cmluZyBtZW1vcnkgYmFzZVVSSV8pIGludGVybmFsIHZpcnR1YWwgewogICAgICAgIF9iYXNlVVJJID0gYmFzZVVSSV87CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIGludm9rZSB7SUVSQzcyMVJlY2VpdmVyLW9uRVJDNzIxUmVjZWl2ZWR9IG9uIGEgdGFyZ2V0IGFkZHJlc3MuCiAgICAgKiBUaGUgY2FsbCBpcyBub3QgZXhlY3V0ZWQgaWYgdGhlIHRhcmdldCBhZGRyZXNzIGlzIG5vdCBhIGNvbnRyYWN0LgogICAgICoKICAgICAqIEBwYXJhbSBmcm9tIGFkZHJlc3MgcmVwcmVzZW50aW5nIHRoZSBwcmV2aW91cyBvd25lciBvZiB0aGUgZ2l2ZW4gdG9rZW4gSUQKICAgICAqIEBwYXJhbSB0byB0YXJnZXQgYWRkcmVzcyB0aGF0IHdpbGwgcmVjZWl2ZSB0aGUgdG9rZW5zCiAgICAgKiBAcGFyYW0gdG9rZW5JZCB1aW50MjU2IElEIG9mIHRoZSB0b2tlbiB0byBiZSB0cmFuc2ZlcnJlZAogICAgICogQHBhcmFtIF9kYXRhIGJ5dGVzIG9wdGlvbmFsIGRhdGEgdG8gc2VuZCBhbG9uZyB3aXRoIHRoZSBjYWxsCiAgICAgKiBAcmV0dXJuIGJvb2wgd2hldGhlciB0aGUgY2FsbCBjb3JyZWN0bHkgcmV0dXJuZWQgdGhlIGV4cGVjdGVkIG1hZ2ljIHZhbHVlCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9jaGVja09uRVJDNzIxUmVjZWl2ZWQoYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHRva2VuSWQsIGJ5dGVzIG1lbW9yeSBfZGF0YSkKICAgICAgICBwcml2YXRlIHJldHVybnMgKGJvb2wpCiAgICB7CiAgICAgICAgaWYgKCF0by5pc0NvbnRyYWN0KCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGJ5dGVzIG1lbW9yeSByZXR1cm5kYXRhID0gdG8uZnVuY3Rpb25DYWxsKGFiaS5lbmNvZGVXaXRoU2VsZWN0b3IoCiAgICAgICAgICAgIElFUkM3MjFSZWNlaXZlcih0bykub25FUkM3MjFSZWNlaXZlZC5zZWxlY3RvciwKICAgICAgICAgICAgX21zZ1NlbmRlcigpLAogICAgICAgICAgICBmcm9tLAogICAgICAgICAgICB0b2tlbklkLAogICAgICAgICAgICBfZGF0YQogICAgICAgICksICJFUkM3MjE6IHRyYW5zZmVyIHRvIG5vbiBFUkM3MjFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwogICAgICAgIGJ5dGVzNCByZXR2YWwgPSBhYmkuZGVjb2RlKHJldHVybmRhdGEsIChieXRlczQpKTsKICAgICAgICByZXR1cm4gKHJldHZhbCA9PSBfRVJDNzIxX1JFQ0VJVkVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBgdG9gIHRvIG9wZXJhdGUgb24gYHRva2VuSWRgCiAgICAgKgogICAgICogRW1pdHMgYW4ge0FwcHJvdmFsfSBldmVudC4KICAgICAqLwogICAgZnVuY3Rpb24gX2FwcHJvdmUoYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkKSBpbnRlcm5hbCB2aXJ0dWFsIHsKICAgICAgICBfdG9rZW5BcHByb3ZhbHNbdG9rZW5JZF0gPSB0bzsKICAgICAgICBlbWl0IEFwcHJvdmFsKEVSQzcyMS5vd25lck9mKHRva2VuSWQpLCB0bywgdG9rZW5JZCk7IC8vIGludGVybmFsIG93bmVyCiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEhvb2sgdGhhdCBpcyBjYWxsZWQgYmVmb3JlIGFueSB0b2tlbiB0cmFuc2Zlci4gVGhpcyBpbmNsdWRlcyBtaW50aW5nCiAgICAgKiBhbmQgYnVybmluZy4KICAgICAqCiAgICAgKiBDYWxsaW5nIGNvbmRpdGlvbnM6CiAgICAgKgogICAgICogLSBXaGVuIGBmcm9tYCBhbmQgYHRvYCBhcmUgYm90aCBub24temVybywgYGBmcm9tYGAncyBgdG9rZW5JZGAgd2lsbCBiZQogICAgICogdHJhbnNmZXJyZWQgdG8gYHRvYC4KICAgICAqIC0gV2hlbiBgZnJvbWAgaXMgemVybywgYHRva2VuSWRgIHdpbGwgYmUgbWludGVkIGZvciBgdG9gLgogICAgICogLSBXaGVuIGB0b2AgaXMgemVybywgYGBmcm9tYGAncyBgdG9rZW5JZGAgd2lsbCBiZSBidXJuZWQuCiAgICAgKiAtIGBmcm9tYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqIC0gYHRvYCBjYW5ub3QgYmUgdGhlIHplcm8gYWRkcmVzcy4KICAgICAqCiAgICAgKiBUbyBsZWFybiBtb3JlIGFib3V0IGhvb2tzLCBoZWFkIHRvIHhyZWY6Uk9PVDpleHRlbmRpbmctY29udHJhY3RzLmFkb2MjdXNpbmctaG9va3NbVXNpbmcgSG9va3NdLgogICAgICovCiAgICBmdW5jdGlvbiBfYmVmb3JlVG9rZW5UcmFuc2ZlcihhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdG9rZW5JZCkgaW50ZXJuYWwgdmlydHVhbCB7IH0KfQoKLy8gRmlsZTogb3BlbnplcHBlbGluLXNvbGlkaXR5L2NvbnRyYWN0cy9hY2Nlc3MvT3duYWJsZS5zb2wKCi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQKCnByYWdtYSBzb2xpZGl0eSA+PTAuNi4wIDwwLjguMDsKCi8qKgogKiBAZGV2IENvbnRyYWN0IG1vZHVsZSB3aGljaCBwcm92aWRlcyBhIGJhc2ljIGFjY2VzcyBjb250cm9sIG1lY2hhbmlzbSwgd2hlcmUKICogdGhlcmUgaXMgYW4gYWNjb3VudCAoYW4gb3duZXIpIHRoYXQgY2FuIGJlIGdyYW50ZWQgZXhjbHVzaXZlIGFjY2VzcyB0bwogKiBzcGVjaWZpYyBmdW5jdGlvbnMuCiAqCiAqIEJ5IGRlZmF1bHQsIHRoZSBvd25lciBhY2NvdW50IHdpbGwgYmUgdGhlIG9uZSB0aGF0IGRlcGxveXMgdGhlIGNvbnRyYWN0LiBUaGlzCiAqIGNhbiBsYXRlciBiZSBjaGFuZ2VkIHdpdGgge3RyYW5zZmVyT3duZXJzaGlwfS4KICoKICogVGhpcyBtb2R1bGUgaXMgdXNlZCB0aHJvdWdoIGluaGVyaXRhbmNlLiBJdCB3aWxsIG1ha2UgYXZhaWxhYmxlIHRoZSBtb2RpZmllcgogKiBgb25seU93bmVyYCwgd2hpY2ggY2FuIGJlIGFwcGxpZWQgdG8geW91ciBmdW5jdGlvbnMgdG8gcmVzdHJpY3QgdGhlaXIgdXNlIHRvCiAqIHRoZSBvd25lci4KICovCmFic3RyYWN0IGNvbnRyYWN0IE93bmFibGUgaXMgQ29udGV4dCB7CiAgICBhZGRyZXNzIHByaXZhdGUgX293bmVyOwoKICAgIGV2ZW50IE93bmVyc2hpcFRyYW5zZmVycmVkKGFkZHJlc3MgaW5kZXhlZCBwcmV2aW91c093bmVyLCBhZGRyZXNzIGluZGV4ZWQgbmV3T3duZXIpOwoKICAgIC8qKgogICAgICogQGRldiBJbml0aWFsaXplcyB0aGUgY29udHJhY3Qgc2V0dGluZyB0aGUgZGVwbG95ZXIgYXMgdGhlIGluaXRpYWwgb3duZXIuCiAgICAgKi8KICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBhZGRyZXNzIG1zZ1NlbmRlciA9IF9tc2dTZW5kZXIoKTsKICAgICAgICBfb3duZXIgPSBtc2dTZW5kZXI7CiAgICAgICAgZW1pdCBPd25lcnNoaXBUcmFuc2ZlcnJlZChhZGRyZXNzKDApLCBtc2dTZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBhZGRyZXNzIG9mIHRoZSBjdXJyZW50IG93bmVyLgogICAgICovCiAgICBmdW5jdGlvbiBvd25lcigpIHB1YmxpYyB2aWV3IHZpcnR1YWwgcmV0dXJucyAoYWRkcmVzcykgewogICAgICAgIHJldHVybiBfb3duZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFRocm93cyBpZiBjYWxsZWQgYnkgYW55IGFjY291bnQgb3RoZXIgdGhhbiB0aGUgb3duZXIuCiAgICAgKi8KICAgIG1vZGlmaWVyIG9ubHlPd25lcigpIHsKICAgICAgICByZXF1aXJlKG93bmVyKCkgPT0gX21zZ1NlbmRlcigpLCAiT3duYWJsZTogY2FsbGVyIGlzIG5vdCB0aGUgb3duZXIiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBMZWF2ZXMgdGhlIGNvbnRyYWN0IHdpdGhvdXQgb3duZXIuIEl0IHdpbGwgbm90IGJlIHBvc3NpYmxlIHRvIGNhbGwKICAgICAqIGBvbmx5T3duZXJgIGZ1bmN0aW9ucyBhbnltb3JlLiBDYW4gb25seSBiZSBjYWxsZWQgYnkgdGhlIGN1cnJlbnQgb3duZXIuCiAgICAgKgogICAgICogTk9URTogUmVub3VuY2luZyBvd25lcnNoaXAgd2lsbCBsZWF2ZSB0aGUgY29udHJhY3Qgd2l0aG91dCBhbiBvd25lciwKICAgICAqIHRoZXJlYnkgcmVtb3ZpbmcgYW55IGZ1bmN0aW9uYWxpdHkgdGhhdCBpcyBvbmx5IGF2YWlsYWJsZSB0byB0aGUgb3duZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJlbm91bmNlT3duZXJzaGlwKCkgcHVibGljIHZpcnR1YWwgb25seU93bmVyIHsKICAgICAgICBlbWl0IE93bmVyc2hpcFRyYW5zZmVycmVkKF9vd25lciwgYWRkcmVzcygwKSk7CiAgICAgICAgX293bmVyID0gYWRkcmVzcygwKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgVHJhbnNmZXJzIG93bmVyc2hpcCBvZiB0aGUgY29udHJhY3QgdG8gYSBuZXcgYWNjb3VudCAoYG5ld093bmVyYCkuCiAgICAgKiBDYW4gb25seSBiZSBjYWxsZWQgYnkgdGhlIGN1cnJlbnQgb3duZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHRyYW5zZmVyT3duZXJzaGlwKGFkZHJlc3MgbmV3T3duZXIpIHB1YmxpYyB2aXJ0dWFsIG9ubHlPd25lciB7CiAgICAgICAgcmVxdWlyZShuZXdPd25lciAhPSBhZGRyZXNzKDApLCAiT3duYWJsZTogbmV3IG93bmVyIGlzIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICBlbWl0IE93bmVyc2hpcFRyYW5zZmVycmVkKF9vd25lciwgbmV3T3duZXIpOwogICAgICAgIF9vd25lciA9IG5ld093bmVyOwogICAgfQp9CgovLyBGaWxlOiBjb250cmFjdHMvZXJjNzIxL1Rlc3RORlQuc29sCgovLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUCgpwcmFnbWEgc29saWRpdHkgXjAuNi4wOwoKCgoKY29udHJhY3QgVGVzdE5GVCBpcyBFUkM3MjEsIE93bmFibGUgewogICAgdWludDI1NiBwcml2YXRlIF9sYXN0VG9rZW5JZCA9IDA7CgogICAgY29uc3RydWN0b3IoCiAgICAgICAgc3RyaW5nIG1lbW9yeSBfbmFtZSwgCiAgICAgICAgc3RyaW5nIG1lbW9yeSBfc3ltYm9sLAogICAgICAgIHN0cmluZyBtZW1vcnkgX2Jhc2VVUkkKICAgICkgcHVibGljIEVSQzcyMShfbmFtZSwgX3N5bWJvbCl7IAogICAgICAgIF9zZXRCYXNlVVJJKF9iYXNlVVJJKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2VuZXJhdGVUb2tlbklkKCkgaW50ZXJuYWwgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiArK19sYXN0VG9rZW5JZDsKICAgIH0KCiAgICBmdW5jdGlvbiBjcmVhdGVUb2tlbihhZGRyZXNzIHRvLCBzdHJpbmcgY2FsbGRhdGEgbWV0YWRhdGFVUkkpIGV4dGVybmFsIG9ubHlPd25lciByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgdWludDI1NiBpZCA9IF9nZW5lcmF0ZVRva2VuSWQoKTsKICAgICAgICBfbWludCh0bywgaWQpOwogICAgICAgIF9zZXRUb2tlblVSSShpZCwgbWV0YWRhdGFVUkkpOwogICAgICAgIHJldHVybiBpZDsKICAgIH0KCiAgICBmdW5jdGlvbiBjcmVhdGVUb2tlbihhZGRyZXNzIHRvKSBleHRlcm5hbCBvbmx5T3duZXIgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgaWQgPSBfZ2VuZXJhdGVUb2tlbklkKCk7CiAgICAgICAgX21pbnQodG8sIGlkKTsKICAgICAgICByZXR1cm4gaWQ7CiAgICB9Cn0K",
    "constructor_arguments": "",
    "evm_version":"byzantium"
}

Query Parameters

Parameter

Description

contract_hash

type: String

value: Address of contract

required: true

contract_name

type: String

value: Name of contract

required: true

compiler

type: String

value: Solidity compiler version

required: true

runs_optimizer

type: Integer

value: Value of time which running optimizer

required: true

optimization_enabled

type: Integer

value: Identify if optimization is enable or not (1: enable, Other number: not)

required: true

contract_source

type: String

value: Solidity contract code(base64 encoding)

required: true

constructor_arguments

type: String

value: Arguments of constructor

required: true

evm_version

type: String

value: Evm version used when compiling

required: false

libraries

type: List<Object>

value: Library list used for the contract

required: false