#!/bin/bash export SCHEME_HOST="http://localhost:3001" function safepkt_backend_00_list_steps() { curl --no-progress-meter "${SCHEME_HOST}"/steps | jq } function safepkt_backend_01_upload_source() { curl --no-progress-meter --request POST \ --url "${SCHEME_HOST}"/source \ --header 'Content-Type: application/json' \ --data '{"source":"Ly8gQ29weXJpZ2h0IDIwMTgtMjAyMCBQYXJpdHkgVGVjaG5vbG9naWVzIChVSykgTHRkLgovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAovLwovLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCi8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCi8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgovLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCi8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKLy8hICMgUGxhaW4gTXVsdGlzaWcgV2FsbGV0Ci8vIQovLyEgVGhpcyBpbXBsZW1lbnRzIGEgcGxhaW4gbXVsdGkgb3duZXIgd2FsbGV0LgovLyEKLy8hICMjIFdhcm5pbmcKLy8hCi8vISBUaGlzIGNvbnRyYWN0IGlzIGFuICpleGFtcGxlKi4gSXQgaXMgbmVpdGhlciBhdWRpdGVkIG5vciBlbmRvcnNlZCBmb3IgcHJvZHVjdGlvbiB1c2UuCi8vISBEbyAqKm5vdCoqIHJlbHkgb24gaXQgdG8ga2VlcCBhbnl0aGluZyBvZiB2YWx1ZSBzZWN1cmUuCi8vIQovLyEgIyMgT3ZlcnZpZXcKLy8hCi8vISBFYWNoIGluc3RhbnRpYXRpb24gb2YgdGhpcyBjb250cmFjdCBoYXMgYSBzZXQgb2YgYG93bmVyc2AgYW5kIGEgYHJlcXVpcmVtZW50YCBvZgovLyEgaG93IG1hbnkgb2YgdGhlbSBuZWVkIHRvIGFncmVlIG9uIGEgYFRyYW5zYWN0aW9uYCBmb3IgaXQgdG8gYmUgYWJsZSB0byBiZSBleGVjdXRlZC4KLy8hIEV2ZXJ5IG93bmVyIGNhbiBzdWJtaXQgYSB0cmFuc2FjdGlvbiBhbmQgd2hlbiBlbm91Z2ggb2YgdGhlIG90aGVyIG93bmVycyBjb25maXJtCi8vISBpdCB3aWxsIGJlIGFibGUgdG8gYmUgZXhlY3V0ZWQuIFRoZSBmb2xsb3dpbmcgaW52YXJpYW50IGlzIGVuZm9yY2VkIGJ5IHRoZSBjb250cmFjdDoKLy8hCi8vISBgYGBpZ25vcmUKLy8hIDAgPCByZXF1aXJlbWVudCAmJiByZXF1aXJlbWVudCA8PSBvd25lcnMgJiYgb3duZXJzIDw9IE1BWF9PV05FUlMKLy8hIGBgYAovLyEKLy8hICMjIEVycm9yIEhhbmRsaW5nCi8vIQovLyEgV2l0aCB0aGUgZXhlY2VwdGlvbiBvZiBgZXhlY3V0ZV90cmFuc2FjdGlvbmAgbm8gZXJyb3IgY29uZGl0aW9ucyBhcmUgc2lnbmFsbGVkCi8vISB0aHJvdWdoIHJldHVybiB0eXBlcy4gQW55IGVycm9yIG9yIGludmFyaWFudCB2aW9sYXRpb24gdHJpZ2dlcnMgYSBwYW5pYyBhbmQgdGhlcmVmb3JlCi8vISByb2xscyBiYWNrIHRoZSB0cmFuc2FjdGlvbi4KLy8hCi8vISAjIyBJbnRlcmZhY2UKLy8hCi8vISBUaGUgaW50ZXJmYWNlIGlzIG1vZGVsbGVkIGFmdGVyIHRoZSBwb3B1bGFyIGdub3NpcyBtdWx0aXNpZyB3YWxsZXQuIEhvd2V2ZXIsIHRoZXJlCi8vISBhcmUgc3VidGxlIHZhcmlhdGlvbnMgZnJvbSB0aGUgaW50ZXJmYWNlLiBGb3IgZXhhbXBsZSB0aGUgYGNvbmZpcm1fdHJhbnNhY3Rpb25gCi8vISB3aWxsIG5ldmVyIHRyaWdnZXIgdGhlIGV4ZWN1dGlvbiBvZiBhIGBUcmFuc2FjdGlvbmAgZXZlbiBpZiB0aGUgdHJlc2hvbGQgaXMgcmVhY2hlZC4KLy8hIEEgY2FsbCBvZiBgZXhlY3V0ZV90cmFuc2FjdGlvbmAgaXMgYWx3YXlzIHJlcXVpcmVkLiBUaGlzIGNhbiBiZSBjYWxsZWQgYnkgYW55b25lLgovLyEKLy8hIEFsbCB0aGUgbWVzc2FnZXMgdGhhdCBhcmUgZGVjbGFyZWQgYXMgb25seSBjYWxsYWJsZSBieSB0aGUgd2FsbGV0IG11c3QgZ28gdGhyb3VnaAovLyEgdGhlIHVzdWFsIHN1Ym1pdCwgY29uZmlybSwgZXhlY3V0ZSBjeWNsZSBhcyBhbnkgb3RoZXIgdHJhbnNhY3Rpb24gdGhhdCBzaG91bGQgYmUKLy8hIGNhbGxlZCBieSB0aGUgd2FsbGV0LiBGb3IgZXhhbXBsZSB0byBhZGQgYW4gb3duZXIgeW91IHdvdWxkIHN1Ym1pdCBhIHRyYW5zYWN0aW9uCi8vISB0aGF0IGNhbGxzIHRoZSB3YWxsZXRzIG93biBgYWRkX293bmVyYCBtZXNzYWdlIHRocm91Z2ggYHN1Ym1pdF90cmFuc2FjdGlvbmAuCi8vIQovLyEgIyMjIE93bmVyIE1hbmFnZW1lbnQKLy8hCi8vISBUaGUgbWVzc2FnZXMgYGFkZF9vd25lcmAsIGByZW1vdmVfb3duZXJgLCBhbmQgYHJlcGxhY2Vfb3duZXJgIGNhbiBiZSB1c2VkIHRvIG1hbmFnZQovLyEgdGhlIG93bmVyIHNldCBhZnRlciBpbnN0YW50aWF0aW9uLgovLyEKLy8hICMjIyBDaGFuZ2luZyB0aGUgUmVxdWlyZW1lbnQKLy8hCi8vISBgY2hhbmdlX3JlcXVpcmVtZW50YCBjYW4gYmUgdXNlZCB0byB0aWdodGVuIG9yIHJlbGF4IHRoZSBgcmVxdWlyZW1lbnRgIG9mIGhvdyBtYW55Ci8vISBvd25lciBzaWduYXR1cmVzIGFyZSBuZWVkZWQgdG8gZXhlY3V0ZSBhIGBUcmFuc2FjdGlvbmAuCi8vIQovLyEgIyMjIFRyYW5zYWN0aW9uIE1hbmFnZW1lbnQKLy8hCi8vISBgc3VibWl0X3RyYW5zYWN0aW9uYCwgYGNhbmNlbF90cmFuc2FjdGlvbmAsIGBjb25maXJtX3RyYW5zYWN0aW9uYCwKLy8hIGByZXZva2VfY29uZmlybWF0aW9uYCBhbmQgYGV4ZWN1dGVfdHJhbnNhY3Rpb25gIGFyZSB0aGUgYnJlYWQgYW5kIGJ1dHRlciBtZXNzYWdlcwovLyEgb2YgdGhpcyBjb250cmFjdC4gVXNlIHRoZW0gdG8gZGlzcGF0Y2ggYXJiaXRyYXJ5IG1lc3NhZ2VzIHRvIG90aGVyIGNvbnRyYWN0cwovLyEgd2l0aCB0aGUgd2FsbGV0IGFzIGEgc2VuZGVyLgoKIyFbY2ZnX2F0dHIobm90KGZlYXR1cmUgPSAic3RkIiksIG5vX3N0ZCldCgp1c2UgaW5rX2xhbmcgYXMgaW5rOwoKI1tpbms6OmNvbnRyYWN0KHZlcnNpb24gPSAiMC4xLjAiKV0KbW9kIHNhZmVwa3RfMzc0NTY3YWI2NyB7CiAgICB1c2UgaW5rX2NvcmU6OnsKICAgICAgICBlbnY6OmNhbGw6OnsKICAgICAgICAgICAgc3RhdGU6OnsKICAgICAgICAgICAgICAgIFNlYWxlZCwKICAgICAgICAgICAgICAgIFVuc2VhbGVkLAogICAgICAgICAgICB9LAogICAgICAgICAgICBDYWxsQnVpbGRlciwKICAgICAgICAgICAgQ2FsbFBhcmFtcywKICAgICAgICB9LAogICAgICAgIHN0b3JhZ2UsCiAgICB9OwogICAgdXNlIGlua19wcmVsdWRlOjp2ZWM6OlZlYzsKICAgIHVzZSBzY2FsZTo6T3V0cHV0OwoKICAgIC8vLyBUdW5lIHRoaXMgdG8geW91ciBsaWtpbmcgYnV0IGJlIHdhcnkgdGhhdCBhbGxvd2luZyB0b28gbWFueSBvd25lcnMgd2lsbCBub3QgcGVyZm9ybSB3ZWxsLgogICAgY29uc3QgTUFYX09XTkVSUzogdTMyID0gNTA7CgogICAgdHlwZSBUcmFuc2FjdGlvbklkID0gdTMyOwogICAgY29uc3QgV1JPTkdfVFJBTlNBQ1RJT05fSUQ6ICZzdHIgPQogICAgICAgICJUaGUgdXNlciBzcGVjaWZpZWQgYW4gaW52YWxpZCB0cmFuc2FjdGlvbiBpZC4gQWJvcnQuIjsKCiAgICAvLy8gQSB3cmFwcGVyIHRoYXQgYWxsb3dzIHVzIHRvIGVuY29kZSBhIGJsb2Igb2YgYnl0ZXMuCiAgICAvLy8KICAgIC8vLyBXZSB1c2UgdGhpcyB0byBwYXNzIHRoZSBzZXQgb2YgdW50eXBlZCAoYnl0ZXMpIHBhcmFtZXRlcnMgdG8gdGhlIGBDYWxsQnVpbGRlcmAuCiAgICBzdHJ1Y3QgQ2FsbElucHV0PCdhPigmJ2EgW3U4XSk7CgogICAgaW1wbDwnYT4gc2NhbGU6OkVuY29kZSBmb3IgQ2FsbElucHV0PCdhPiB7CiAgICAgICAgZm4gZW5jb2RlX3RvPFQ6IE91dHB1dD4oJnNlbGYsIGRlc3Q6ICZtdXQgVCkgewogICAgICAgICAgICBkZXN0LndyaXRlKHNlbGYuMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8vLyBJbmRpY2F0ZXMgd2hldGhlciBhIHRyYW5zYWN0aW9uIGlzIGFscmVhZHkgY29uZmlybWVkIG9yIG5lZWRzIGZ1cnRoZXIgY29uZmlybWF0aW9ucy4KICAgICNbZGVyaXZlKHNjYWxlOjpFbmNvZGUsIHNjYWxlOjpEZWNvZGUsIENsb25lLCBDb3B5KV0KICAgIHB1YiBlbnVtIENvbmZpcm1hdGlvblN0YXR1cyB7CiAgICAgICAgLy8vIFRoZSB0cmFuc2FjdGlvbiBpcyBhbHJlYWR5IGNvbmZpcm1lZC4KICAgICAgICBDb25maXJtZWQsCiAgICAgICAgLy8vIEluZGljYXRlcyBob3cgbWFueSBjb25maXJtYXRpb25zIGFyZSByZW1haW5pbmcuCiAgICAgICAgQ29uZmlybWF0aW9uc05lZWRlZCh1MzIpLAogICAgfQoKICAgIC8vLyBBIFRyYW5zYWN0aW9uIGlzIHdoYXQgZXZlcnkgYG93bmVyYCBjYW4gc3VibWl0IGZvciBjb25maXJtYXRpb24gYnkgb3RoZXIgb3duZXJzLgogICAgLy8vIElmIGVub3VnaCBvd25lcnMgYWdyZWUgaXQgd2lsbCBiZSBleGVjdXRlZCBieSB0aGUgY29udHJhY3QuCiAgICAjW2Rlcml2ZShzY2FsZTo6RW5jb2RlLCBzY2FsZTo6RGVjb2RlLCBzdG9yYWdlOjpGbHVzaCldCiAgICAjW2NmZ19hdHRyKGZlYXR1cmUgPSAiaW5rLWdlbmVyYXRlLWFiaSIsIGRlcml2ZSh0eXBlX21ldGFkYXRhOjpNZXRhZGF0YSkpXQogICAgI1tjZmdfYXR0cihmZWF0dXJlID0gInN0ZCIsIGRlcml2ZShEZWJ1ZywgUGFydGlhbEVxLCBFcSkpXQogICAgcHViIHN0cnVjdCBUcmFuc2FjdGlvbiB7CiAgICAgICAgLy8vIFRoZSBBY2NvdW50SWQgb2YgdGhlIGNvbnRyYWN0IHRoYXQgaXMgY2FsbGVkIGluIHRoaXMgdHJhbnNhY3Rpb24uCiAgICAgICAgY2FsbGVlOiBBY2NvdW50SWQsCiAgICAgICAgLy8vIFRoZSBzZWxlY3RvciBieXRlcyB0aGF0IGlkZW50aWZpZXMgdGhlIGZ1bmN0aW9uIG9mIHRoZSBjYWxsZWUgdGhhdCBzaG91bGQgYmUgY2FsbGVkLgogICAgICAgIHNlbGVjdG9yOiBbdTg7IDRdLAogICAgICAgIC8vLyBUaGUgU0NBTEUgZW5jb2RlZCBwYXJhbWV0ZXJzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGUgY2FsbGVkIGZ1bmN0aW9uLgogICAgICAgIGlucHV0OiBWZWM8dTg+LAogICAgICAgIC8vLyBUaGUgYW1vdW50IG9mIGNoYWluIGJhbGFuY2UgdGhhdCBpcyB0cmFuc2ZlcnJlZCB0byB0aGUgY2FsbGVlLgogICAgICAgIHRyYW5zZmVycmVkX3ZhbHVlOiBCYWxhbmNlLAogICAgICAgIC8vLyBHYXMgbGltaXQgZm9yIHRoZSBleGVjdXRpb24gb2YgdGhlIGNhbGwuCiAgICAgICAgZ2FzX2xpbWl0OiB1NjQsCiAgICB9CgogICAgI1tpbmsoc3RvcmFnZSldCiAgICBzdHJ1Y3QgTXVsdGlzaWdQbGFpbiB7CiAgICAgICAgLy8vIEV2ZXJ5IGVudHJ5IGluIHRoaXMgbWFwIHJlcHJlc2VudHMgdGhlIGNvbmZpcm1hdGlvbiBvZiBhbiBvd25lciBmb3IgYQogICAgICAgIC8vLyB0cmFuc2FjdGlvbi4gVGhpcyBpcyBlZmZlY2l2ZWx5IGEgc2V0IHJhdGhlciB0aGFuIGEgbWFwLgogICAgICAgIGNvbmZpcm1hdGlvbnM6IHN0b3JhZ2U6OkJUcmVlTWFwPChUcmFuc2FjdGlvbklkLCBBY2NvdW50SWQpLCAoKT4sCiAgICAgICAgLy8vIFRoZSBhbW91bnQgb2YgY29uZmlybWF0aW9ucyBmb3IgZXZlcnkgdHJhbnNhY3Rpb24uIFRoaXMgaXMgYSByZWR1bmRhbnQKICAgICAgICAvLy8gaW5mb3JtYXRpb24gYW5kIGlzIGtlcHQgaW4gb3JkZXIgdG8gcHJldmVudCBpdGVyYXRpbmcgdGhyb3VnaCB0aGUKICAgICAgICAvLy8gY29uZmlybWF0aW9uIHNldCB0byBjaGVjayBpZiBhIHRyYW5zYWN0aW9uIGlzIGNvbmZpcm1lZC4KICAgICAgICBjb25maXJtYXRpb25fY291bnQ6IHN0b3JhZ2U6OkJUcmVlTWFwPFRyYW5zYWN0aW9uSWQsIHUzMj4sCiAgICAgICAgLy8vIEp1c3QgdGhlIGxpc3Qgb2YgdHJhbnNhY3Rpb25zLiBJdCBpcyBhIHN0YXNoIGFzIHN0YWJsZSBpZHMgYXJlIG5lY2Vzc2FyeQogICAgICAgIC8vLyBmb3IgcmVmZXJlbmNpbmcgdGhlbSBpbiBjb25maXJtYXRpb24gY2FsbHMuCiAgICAgICAgdHJhbnNhY3Rpb25zOiBzdG9yYWdlOjpTdGFzaDxUcmFuc2FjdGlvbj4sCiAgICAgICAgLy8vIFRoZSBsaXN0IGlzIGEgdmVjdG9yIGJlY2F1c2UgaXRlcmF0aW5nIG92ZXIgaXQgaXMgbmVjZXNzYXJ5IHdoZW4gY2xlYW5pbmcKICAgICAgICAvLy8gdXAgdGhlIGNvbmZpcm1hdGlvbiBzZXQuCiAgICAgICAgb3duZXJzOiBzdG9yYWdlOjpWZWM8QWNjb3VudElkPiwKICAgICAgICAvLy8gUmVkdW5kYW50IGluZm9ybWF0aW9uIHRvIHNwZWVkIHVwIHRoZSBjaGVjayB3aGV0aGVyIGEgY2FsbGVyIGlzIGFuIG93bmVyLgogICAgICAgIGlzX293bmVyOiBzdG9yYWdlOjpCVHJlZU1hcDxBY2NvdW50SWQsICgpPiwKICAgICAgICAvLy8gTWluaW11bSBudW1iZXIgb2Ygb3duZXJzIHRoYXQgaGF2ZSB0byBjb25maXJtIGEgdHJhbnNhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuCiAgICAgICAgcmVxdWlyZW1lbnQ6IHN0b3JhZ2U6OlZhbHVlPHUzMj4sCiAgICB9CgogICAgLy8vIEVtaXR0ZWQgd2hlbiBhbiBvd25lciBjb25maXJtcyBhIHRyYW5zYWN0aW9uLgogICAgI1tpbmsoZXZlbnQpXQogICAgc3RydWN0IENvbmZpcm1hdGlvbiB7CiAgICAgICAgLy8vIFRoZSB0cmFuc2FjdGlvbiB0aGF0IHdhcyBjb25maXJtZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbklkLAogICAgICAgIC8vLyBUaGUgb3duZXIgdGhhdCBzZW50IHRoZSBjb25maXJtYXRpb24uCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIGZyb206IEFjY291bnRJZCwKICAgICAgICAvLy8gVGhlIGNvbmZpcm1hdGlvbiBzdGF0dXMgYWZ0ZXIgdGhpcyBjb25maXJtYXRpb24gd2FzIGFwcGxpZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIHN0YXR1czogQ29uZmlybWF0aW9uU3RhdHVzLAogICAgfQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gYW4gb3duZXIgcmV2b2tlZCBhIGNvbmZpcm1hdGlvbi4KICAgICNbaW5rKGV2ZW50KV0KICAgIHN0cnVjdCBSZXZva2F0aW9uIHsKICAgICAgICAvLy8gVGhlIHRyYW5zYWN0aW9uIHRoYXQgd2FzIHJldm9rZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbklkLAogICAgICAgIC8vLyBUaGUgb3duZXIgdGhhdCBzZW50IHRoZSByZXZva2F0aW9uLgogICAgICAgICNbaW5rKHRvcGljKV0KICAgICAgICBmcm9tOiBBY2NvdW50SWQsCiAgICB9CgogICAgLy8vIEVtaXR0ZWQgd2hlbiBhbiBvd25lciBzdWJtaXRzIGEgdHJhbnNhY3Rpb24uCiAgICAjW2luayhldmVudCldCiAgICBzdHJ1Y3QgU3VibWlzc2lvbiB7CiAgICAgICAgLy8vIFRoZSB0cmFuc2FjdGlvbiB0aGF0IHdhcyBzdWJtaXR0ZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbklkLAogICAgfQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gYSB0cmFuc2FjdGlvbiB3YXMgY2FuY2VsZWQuCiAgICAjW2luayhldmVudCldCiAgICBzdHJ1Y3QgQ2FuY2VsYXRpb24gewogICAgICAgIC8vLyBUaGUgdHJhbnNhY3Rpb24gdGhhdCB3YXMgY2FuY2VsZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbklkLAogICAgfQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gYSB0cmFuc2FjdGlvbiB3YXMgZXhlY3V0ZWQuCiAgICAjW2luayhldmVudCldCiAgICBzdHJ1Y3QgRXhlY3V0aW9uIHsKICAgICAgICAvLy8gVGhlIHRyYW5zYWN0aW9uIHRoYXQgd2FzIGV4ZWN1dGVkLgogICAgICAgICNbaW5rKHRvcGljKV0KICAgICAgICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25JZCwKICAgICAgICAvLy8gSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHRyYW5zYWN0aW9uIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseS4gSWYgc28gdGhlIGBPa2AgdmFsdWUgaG9sZHMKICAgICAgICAvLy8gdGhlIG91dHB1dCBpbiBieXRlcy4gVGhlIE9wdGlvbiBpcyBgTm9uZWAgd2hlbiB0aGUgdHJhbnNhY3Rpb24gd2FzIGV4ZWN1dGVkIHRocm91Z2gKICAgICAgICAvLy8gYGludm9rZV90cmFuc2FjdGlvbmAgcmF0aGVyIHRoYW4gYGV2YWx1YXRlX3RyYW5zYWN0aW9uYC4KICAgICAgICAjW2luayh0b3BpYyldCiAgICAgICAgcmVzdWx0OiBSZXN1bHQ8T3B0aW9uPFZlYzx1OD4+LCAoKT4sCiAgICB9CgogICAgLy8vIEVtaXR0ZWQgd2hlbiBhbiBvd25lciBpcyBhZGRlZCB0byB0aGUgd2FsbGV0LgogICAgI1tpbmsoZXZlbnQpXQogICAgc3RydWN0IE93bmVyQWRkaXRpb24gewogICAgICAgIC8vLyBUaGUgb3duZXIgdGhhdCB3YXMgYWRkZWQuCiAgICAgICAgI1tpbmsodG9waWMpXQogICAgICAgIG93bmVyOiBBY2NvdW50SWQsCiAgICB9CgogICAgLy8vIEVtaXR0ZWQgd2hlbiBhbiBvd25lciBpcyByZW1vdmVkIGZyb20gdGhlIHdhbGxldC4KICAgICNbaW5rKGV2ZW50KV0KICAgIHN0cnVjdCBPd25lclJlbW92YWwgewogICAgICAgIC8vLyBUaGUgb3duZXIgdGhhdCB3YXMgcmVtb3ZlZC4KICAgICAgICAjW2luayh0b3BpYyldCiAgICAgICAgb3duZXI6IEFjY291bnRJZCwKICAgIH0KCiAgICAvLy8gRW1pdHRlZCB3aGVuIHRoZSByZXF1aXJlbWVudCBjaGFuZ2VkLgogICAgI1tpbmsoZXZlbnQpXQogICAgc3RydWN0IFJlcXVpcmVtZW50Q2hhbmdlIHsKICAgICAgICAvLy8gVGhlIG5ldyByZXF1aXJlbWVudCB2YWx1ZS4KICAgICAgICBuZXdfcmVxdWlyZW1lbnQ6IHUzMiwKICAgIH0KCiAgICBpbXBsIE11bHRpc2lnUGxhaW4gewogICAgICAgIC8vLyBUaGUgb25seSBjb25zdHJ1Y3RvciBvZiB0aGUgY29udHJhY3QuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIEEgbGlzdCBvZiBvd25lcnMgbXVzdCBiZSBzdXBwbGllZCBhbmQgYSBudW1iZXIgb2YgaG93IG1hbnkgb2YgdGhlbSBtdXN0CiAgICAgICAgLy8vIGNvbmZpcm0gYSB0cmFuc2FjdGlvbi4gRHVwbGljYXRlIG93bmVycyBhcmUgc2lsZW50bHkgZHJvcHBlZC4KICAgICAgICAvLy8KICAgICAgICAvLy8gIyBQYW5pY3MKICAgICAgICAvLy8KICAgICAgICAvLy8gSWYgYHJlcXVpcmVtZW50YCB2aW9sYXRlcyBvdXIgaW52YXJpYW50LgogICAgICAgICNbaW5rKGNvbnN0cnVjdG9yKV0KICAgICAgICBmbiBuZXcoJm11dCBzZWxmLCByZXF1aXJlbWVudDogdTMyLCBvd25lcnM6IFZlYzxBY2NvdW50SWQ+KSB7CiAgICAgICAgICAgIGZvciBvd25lciBpbiAmb3duZXJzIHsKICAgICAgICAgICAgICAgIHNlbGYuaXNfb3duZXIuaW5zZXJ0KCpvd25lciwgKCkpOwogICAgICAgICAgICAgICAgc2VsZi5vd25lcnMucHVzaCgqb3duZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZV9yZXF1aXJlbWVudF9pc192YWxpZChzZWxmLm93bmVycy5sZW4oKSwgcmVxdWlyZW1lbnQpOwogICAgICAgICAgICBhc3NlcnQhKHNlbGYuaXNfb3duZXIubGVuKCkgPT0gc2VsZi5vd25lcnMubGVuKCkpOwogICAgICAgICAgICBzZWxmLnJlcXVpcmVtZW50LnNldChyZXF1aXJlbWVudCk7CiAgICAgICAgfQoKICAgICAgICAvLy8gQWRkIGEgbmV3IG93bmVyIHRvIHRoZSBjb250cmFjdC4KICAgICAgICAvLy8KICAgICAgICAvLy8gT25seSBjYWxsYWJsZSBieSB0aGUgd2FsbGV0IGl0c2VsZi4KICAgICAgICAvLy8KICAgICAgICAvLy8gIyBQYW5pY3MKICAgICAgICAvLy8KICAgICAgICAvLy8gSWYgdGhlIG93bmVyIGFscmVhZHkgZXhpc3RzLgogICAgICAgIC8vLwogICAgICAgIC8vLyAjIEV4YW1wbGVzCiAgICAgICAgLy8vCiAgICAgICAgLy8vIFNpbmNlIHRoaXMgbWVzc2FnZSBtdXN0IGJlIHNlbmQgYnkgdGhlIHdhbGxldCBpdHNlbGYgaXQgaGFzIHRvIGJlIGJ1aWxkIGFzIGEKICAgICAgICAvLy8gYFRyYW5zYWN0aW9uYCBhbmQgZGlzcGF0Y2hlZCB0aHJvdWdoIGBzdWJtaXRfdHJhbnNhY3Rpb25gICsgYGludm9rZV90cmFuc2FjdGlvbmA6CiAgICAgICAgLy8vIGBgYAogICAgICAgIC8vLyB1c2UgaW5rX2NvcmU6OmVudjo6Y2FsbHtDYWxsRGF0YSwgQ2FsbFBhcmFtcywgU2VsZWN0b3J9OwogICAgICAgIC8vLwogICAgICAgIC8vLyAvLyBhZGRyZXNzIG9mIGFuIGV4aXN0aW5nIE11bHRpU2lnUGxhaW4gY29udHJhY3QKICAgICAgICAvLy8gbGV0IHdhbGxldF9pZDogQWNjb3VudElkID0gWzd1ODsgMzJdLmludG8oKTsKICAgICAgICAvLy8KICAgICAgICAvLy8gLy8gZmlyc3QgY3JlYXRlIHRoZSB0cmFuc2FjdGlvbiB0aGF0IGFkZHMgYGFsaWNlYCB0aHJvdWdoIGBhZGRfb3duZXJgCiAgICAgICAgLy8vIGxldCBhbGljZTogQWNjb3VudElkID0gWzF1ODsgMzJdLmludG8oKTsKICAgICAgICAvLy8gbGV0IG11dCBjYWxsID0gQ2FsbERhdGE6Om5ldyhTZWxlY3Rvcjo6ZnJvbV9zdHIoImFkZF9vd25lciIpKTsKICAgICAgICAvLy8gY2FsbC5wdXNoX2FyZygmYWxpY2UpOwogICAgICAgIC8vLyBsZXQgdHJhbnNhY3Rpb24gPSBUcmFuc2FjdGlvbiB7CiAgICAgICAgLy8vICAgICBjYWxsZWU6IHdhbGxldF9pZCwKICAgICAgICAvLy8gICAgIHNlbGVjdG9yOiBjYWxsLnNlbGVjdG9yKCkudG9fYnl0ZXMoKSwKICAgICAgICAvLy8gICAgIGlucHV0OiBjYWxsLnBhcmFtcygpLnRvX293bmVkKCksCiAgICAgICAgLy8vICAgICB0cmFuc2ZlcnJlZF92YWx1ZTogMCwKICAgICAgICAvLy8gICAgIGdhc19saW1pdDogMAogICAgICAgIC8vLyB9OwogICAgICAgIC8vLwogICAgICAgIC8vLyAvLyBzdWJtaXQgdGhlIHRyYW5zYWN0aW9uIGZvciBjb25maXJtYXRpb24KICAgICAgICAvLy8gbGV0IG11dCBzdWJtaXQgPSBDYWxsUGFyYW1zOjpldmFsKHdhbGxldF9pZCwgU2VsZWN0b3I6OmZyb21fc3RyKCJzdWJtaXRfdHJhbnNhY3Rpb24iKSk7CiAgICAgICAgLy8vIGxldCAoaWQsIF8pICA9IHN1Ym1pdC5wdXNoX2FyZygmdHJhbnNhY3Rpb24pCiAgICAgICAgLy8vICAgICAuZmlyZSgpCiAgICAgICAgLy8vICAgICAuZXhwZWN0KCJzdWJtaXRfdHJhbnNhY3Rpb24gd29uJ3QgcGFuaWMuIik7CiAgICAgICAgLy8vCiAgICAgICAgLy8vIC8vIHdhaXQgdW50aWwgYWxsIHJlcXVpcmVkIG93bmVycyBoYXZlIGNvbmZpcm1lZCBhbmQgdGhlbiBleGVjdXRlIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIC8vLyBsZXQgbXV0IGludm9rZSA9IENhbGxQYXJhbXM6OmV2YWwod2FsbGV0X2lkLCBTZWxlY3Rvcjo6ZnJvbV9zdHIoImludm9rZV90cmFuc2FjdGlvbiIpKTsKICAgICAgICAvLy8gaW52b2tlLnB1c2hfYXJnKCZpZCkuZmlyZSgpOwogICAgICAgIC8vLyBgYGAKICAgICAgICAjW2luayhtZXNzYWdlKV0KICAgICAgICBmbiBhZGRfb3duZXIoJm11dCBzZWxmLCBuZXdfb3duZXI6IEFjY291bnRJZCkgewogICAgICAgICAgICBzZWxmLmVuc3VyZV9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBzZWxmLmVuc3VyZV9ub19vd25lcigmbmV3X293bmVyKTsKICAgICAgICAgICAgZW5zdXJlX3JlcXVpcmVtZW50X2lzX3ZhbGlkKHNlbGYub3duZXJzLmxlbigpICsgMSwgKnNlbGYucmVxdWlyZW1lbnQpOwogICAgICAgICAgICBzZWxmLmlzX293bmVyLmluc2VydChuZXdfb3duZXIsICgpKTsKICAgICAgICAgICAgc2VsZi5vd25lcnMucHVzaChuZXdfb3duZXIpOwogICAgICAgICAgICBzZWxmLmVudigpLmVtaXRfZXZlbnQoT3duZXJBZGRpdGlvbiB7IG93bmVyOiBuZXdfb3duZXIgfSk7CiAgICAgICAgfQoKICAgICAgICAvLy8gUmVtb3ZlIGFuIG93bmVyIGZyb20gdGhlIGNvbnRyYWN0LgogICAgICAgIC8vLwogICAgICAgIC8vLyBPbmx5IGNhbGxhYmxlIGJ5IHRoZSB3YWxsZXQgaXRzZWxmLiBJZiBieSBkb2luZyB0aGlzIHRoZSBhbW91bnQgb2Ygb3duZXJzCiAgICAgICAgLy8vIHdvdWxkIGJlIHNtYWxsZXIgdGhhbiB0aGUgcmVxdWlyZW1lbnQgaXQgaXMgYWRqdXN0ZWQgdG8gYmUgZXhhY3RseSB0aGUKICAgICAgICAvLy8gbnVtYmVyIG9mIG93bmVycy4KICAgICAgICAvLy8KICAgICAgICAvLy8gIyBQYW5pY3MKICAgICAgICAvLy8KICAgICAgICAvLy8gSWYgYG93bmVyYCBpcyBubyBvd25lciBvZiB0aGUgd2FsbGV0LgogICAgICAgICNbaW5rKG1lc3NhZ2UpXQogICAgICAgIGZuIHJlbW92ZV9vd25lcigmbXV0IHNlbGYsIG93bmVyOiBBY2NvdW50SWQpIHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfZnJvbV93YWxsZXQoKTsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfb3duZXIoJm93bmVyKTsKICAgICAgICAgICAgbGV0IGxlbiA9IHNlbGYub3duZXJzLmxlbigpIC0gMTsKICAgICAgICAgICAgbGV0IHJlcXVpcmVtZW50ID0gdTMyOjptaW4obGVuLCAqc2VsZi5yZXF1aXJlbWVudCk7CiAgICAgICAgICAgIGVuc3VyZV9yZXF1aXJlbWVudF9pc192YWxpZChsZW4sIHJlcXVpcmVtZW50KTsKICAgICAgICAgICAgc2VsZi5vd25lcnMuc3dhcF9yZW1vdmUoc2VsZi5vd25lcl9pbmRleCgmb3duZXIpKTsKICAgICAgICAgICAgc2VsZi5pc19vd25lci5yZW1vdmUoJm93bmVyKTsKICAgICAgICAgICAgc2VsZi5yZXF1aXJlbWVudC5zZXQocmVxdWlyZW1lbnQpOwogICAgICAgICAgICBzZWxmLmNsZWFuX293bmVyX2NvbmZpcm1hdGlvbnMoJm93bmVyKTsKICAgICAgICAgICAgc2VsZi5lbnYoKS5lbWl0X2V2ZW50KE93bmVyUmVtb3ZhbCB7IG93bmVyIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8vIFJlcGxhY2UgYW4gb3duZXIgZnJvbSB0aGUgY29udHJhY3Qgd2l0aCBhIG5ldyBvbmUuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIE9ubHkgY2FsbGFibGUgYnkgdGhlIHdhbGxldCBpdHNlbGYuCiAgICAgICAgLy8vCiAgICAgICAgLy8vICMgUGFuaWNzCiAgICAgICAgLy8vCiAgICAgICAgLy8vIElmIGBvbGRfb3duZXJgIGlzIG5vIG93bmVyIG9yIGlmIGBuZXdfb3duZXJgIGFscmVhZHkgaXMgb25lLgogICAgICAgICNbaW5rKG1lc3NhZ2UpXQogICAgICAgIGZuIHJlcGxhY2Vfb3duZXIoJm11dCBzZWxmLCBvbGRfb3duZXI6IEFjY291bnRJZCwgbmV3X293bmVyOiBBY2NvdW50SWQpIHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfZnJvbV93YWxsZXQoKTsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfb3duZXIoJm9sZF9vd25lcik7CiAgICAgICAgICAgIHNlbGYuZW5zdXJlX25vX293bmVyKCZuZXdfb3duZXIpOwogICAgICAgICAgICBzZWxmLm93bmVycwogICAgICAgICAgICAgICAgLnJlcGxhY2Uoc2VsZi5vd25lcl9pbmRleCgmb2xkX293bmVyKSwgfHwgbmV3X293bmVyKTsKICAgICAgICAgICAgc2VsZi5pc19vd25lci5yZW1vdmUoJm9sZF9vd25lcik7CiAgICAgICAgICAgIHNlbGYuaXNfb3duZXIuaW5zZXJ0KG5ld19vd25lciwgKCkpOwogICAgICAgICAgICBzZWxmLmNsZWFuX293bmVyX2NvbmZpcm1hdGlvbnMoJm9sZF9vd25lcik7CiAgICAgICAgICAgIHNlbGYuZW52KCkuZW1pdF9ldmVudChPd25lclJlbW92YWwgeyBvd25lcjogb2xkX293bmVyIH0pOwogICAgICAgICAgICBzZWxmLmVudigpLmVtaXRfZXZlbnQoT3duZXJBZGRpdGlvbiB7IG93bmVyOiBuZXdfb3duZXIgfSk7CiAgICAgICAgfQoKICAgICAgICAvLy8gQ2hhbmdlIHRoZSByZXF1aXJlbWVudCB0byBhIG5ldyB2YWx1ZS4KICAgICAgICAvLy8KICAgICAgICAvLy8gT25seSBjYWxsYWJsZSBieSB0aGUgd2FsbGV0IGl0c2VsZi4KICAgICAgICAvLy8KICAgICAgICAvLy8gIyBQYW5pY3MKICAgICAgICAvLy8KICAgICAgICAvLy8gSWYgdGhlIGBuZXdfcmVxdWlyZW1lbnRgIHZpb2xhdGVzIG91ciBpbnZhcmlhbnQuCiAgICAgICAgI1tpbmsobWVzc2FnZSldCiAgICAgICAgZm4gY2hhbmdlX3JlcXVpcmVtZW50KCZtdXQgc2VsZiwgbmV3X3JlcXVpcmVtZW50OiB1MzIpIHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfZnJvbV93YWxsZXQoKTsKICAgICAgICAgICAgZW5zdXJlX3JlcXVpcmVtZW50X2lzX3ZhbGlkKHNlbGYub3duZXJzLmxlbigpLCBuZXdfcmVxdWlyZW1lbnQpOwogICAgICAgICAgICBzZWxmLnJlcXVpcmVtZW50LnNldChuZXdfcmVxdWlyZW1lbnQpOwogICAgICAgICAgICBzZWxmLmVudigpLmVtaXRfZXZlbnQoUmVxdWlyZW1lbnRDaGFuZ2UgeyBuZXdfcmVxdWlyZW1lbnQgfSk7CiAgICAgICAgfQoKICAgICAgICAvLy8gQWRkIGEgbmV3IHRyYW5zYWN0aW9uIGNhbmRpYXRlIHRvIHRoZSBjb250cmFjdC4KICAgICAgICAvLy8KICAgICAgICAvLy8gVGhpcyBhbHNvIGNvbmZpcm1zIHRoZSB0cmFuc2FjdGlvbiBmb3IgdGhlIGNhbGxlci4gVGhpcyBjYW4gYmUgY2FsbGVkIGJ5IGFueSBvd25lci4KICAgICAgICAjW2luayhtZXNzYWdlKV0KICAgICAgICBmbiBzdWJtaXRfdHJhbnNhY3Rpb24oCiAgICAgICAgICAgICZtdXQgc2VsZiwKICAgICAgICAgICAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLAogICAgICAgICkgLT4gKFRyYW5zYWN0aW9uSWQsIENvbmZpcm1hdGlvblN0YXR1cykgewogICAgICAgICAgICBzZWxmLmVuc3VyZV9jYWxsZXJfaXNfb3duZXIoKTsKICAgICAgICAgICAgbGV0IHRyYW5zX2lkID0gc2VsZi50cmFuc2FjdGlvbnMucHV0KHRyYW5zYWN0aW9uKTsKICAgICAgICAgICAgc2VsZi5lbnYoKS5lbWl0X2V2ZW50KFN1Ym1pc3Npb24gewogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IHRyYW5zX2lkLAogICAgICAgICAgICB9KTsKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgdHJhbnNfaWQsCiAgICAgICAgICAgICAgICBzZWxmLmNvbmZpcm1fYnlfY2FsbGVyKHNlbGYuZW52KCkuY2FsbGVyKCksIHRyYW5zX2lkKSwKICAgICAgICAgICAgKQogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZSBhIHRyYW5zYWN0aW9uIGZyb20gdGhlIGNvbnRyYWN0LgogICAgICAgIC8vLyBPbmx5IGNhbGxhYmxlIGJ5IHRoZSB3YWxsZXQgaXRzZWxmLgogICAgICAgIC8vLwogICAgICAgIC8vLyAjIFBhbmljcwogICAgICAgIC8vLwogICAgICAgIC8vLyBJZiBgdHJhbnNfaWRgIGlzIG5vIHZhbGlkIHRyYW5zYWN0aW9uIGlkLgogICAgICAgICNbaW5rKG1lc3NhZ2UpXQogICAgICAgIGZuIGNhbmNlbF90cmFuc2FjdGlvbigmbXV0IHNlbGYsIHRyYW5zX2lkOiBUcmFuc2FjdGlvbklkKSB7CiAgICAgICAgICAgIHNlbGYuZW5zdXJlX2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGlmIHNlbGYudGFrZV90cmFuc2FjdGlvbih0cmFuc19pZCkuaXNfc29tZSgpIHsKICAgICAgICAgICAgICAgIHNlbGYuZW52KCkuZW1pdF9ldmVudChDYW5jZWxhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IHRyYW5zX2lkLAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBDb25maXJtIGEgdHJhbnNhY3Rpb24gZm9yIHRoZSBzZW5kZXIgdGhhdCB3YXMgc3VibWl0dGVkIGJ5IGFueSBvd25lci4KICAgICAgICAvLy8KICAgICAgICAvLy8gVGhpcyBjYW4gYmUgY2FsbGVkIGJ5IGFueSBvd25lci4KICAgICAgICAvLy8KICAgICAgICAvLy8gIyBQYW5pY3MKICAgICAgICAvLy8KICAgICAgICAvLy8gSWYgYHRyYW5zX2lkYCBpcyBubyB2YWxpZCB0cmFuc2FjdGlvbiBpZC4KICAgICAgICAjW2luayhtZXNzYWdlKV0KICAgICAgICBmbiBjb25maXJtX3RyYW5zYWN0aW9uKCZtdXQgc2VsZiwgdHJhbnNfaWQ6IFRyYW5zYWN0aW9uSWQpIC0+IENvbmZpcm1hdGlvblN0YXR1cyB7CiAgICAgICAgICAgIHNlbGYuZW5zdXJlX2NhbGxlcl9pc19vd25lcigpOwogICAgICAgICAgICBzZWxmLmVuc3VyZV90cmFuc2FjdGlvbl9leGlzdHModHJhbnNfaWQpOwogICAgICAgICAgICBzZWxmLmNvbmZpcm1fYnlfY2FsbGVyKHNlbGYuZW52KCkuY2FsbGVyKCksIHRyYW5zX2lkKQogICAgICAgIH0KCiAgICAgICAgLy8vIFJldm9rZSB0aGUgc2VuZGVycyBjb25maXJtYXRpb24uCiAgICAgICAgLy8vCiAgICAgICAgLy8vIFRoaXMgY2FuIGJlIGNhbGxlZCBieSBhbnkgb3duZXIuCiAgICAgICAgLy8vCiAgICAgICAgLy8vICMgUGFuaWNzCiAgICAgICAgLy8vCiAgICAgICAgLy8vIElmIGB0cmFuc19pZGAgaXMgbm8gdmFsaWQgdHJhbnNhY3Rpb24gaWQuCiAgICAgICAgI1tpbmsobWVzc2FnZSldCiAgICAgICAgZm4gcmV2b2tlX2NvbmZpcm1hdGlvbigmbXV0IHNlbGYsIHRyYW5zX2lkOiBUcmFuc2FjdGlvbklkKSB7CiAgICAgICAgICAgIHNlbGYuZW5zdXJlX2NhbGxlcl9pc19vd25lcigpOwogICAgICAgICAgICBsZXQgY2FsbGVyID0gc2VsZi5lbnYoKS5jYWxsZXIoKTsKICAgICAgICAgICAgaWYgc2VsZi5jb25maXJtYXRpb25zLnJlbW92ZSgmKHRyYW5zX2lkLCBjYWxsZXIpKS5pc19zb21lKCkgewogICAgICAgICAgICAgICAgKnNlbGYuY29uZmlybWF0aW9uX2NvdW50LmVudHJ5KHRyYW5zX2lkKS5vcl9pbnNlcnQoMSkgLT0gMTsKICAgICAgICAgICAgICAgIHNlbGYuZW52KCkuZW1pdF9ldmVudChSZXZva2F0aW9uIHsKICAgICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogdHJhbnNfaWQsCiAgICAgICAgICAgICAgICAgICAgZnJvbTogY2FsbGVyLAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBJbnZva2UgYSBjb25maXJtZWQgZXhlY3V0aW9uIHdpdGhvdXQgZ2V0dGluZyBpdHMgb3V0cHV0LgogICAgICAgIC8vLwogICAgICAgIC8vLyBJdHMgcmV0dXJuIHZhbHVlIGluZGljYXRlcyB3aGV0aGVyIHRoZSBjYWxsZWQgdHJhbnNhY3Rpb24gd2FzIHN1Y2Nlc3NmdWwuCiAgICAgICAgLy8vIFRoaXMgY2FuIGJlIGNhbGxlZCBieSBhbnlvbmUuCiAgICAgICAgI1tpbmsobWVzc2FnZSldCiAgICAgICAgZm4gaW52b2tlX3RyYW5zYWN0aW9uKCZtdXQgc2VsZiwgdHJhbnNfaWQ6IFRyYW5zYWN0aW9uSWQpIC0+IFJlc3VsdDwoKSwgKCk+IHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfY29uZmlybWVkKHRyYW5zX2lkKTsKICAgICAgICAgICAgbGV0IHQgPSBzZWxmLnRha2VfdHJhbnNhY3Rpb24odHJhbnNfaWQpLmV4cGVjdChXUk9OR19UUkFOU0FDVElPTl9JRCk7CiAgICAgICAgICAgIGxldCByZXN1bHQgPSBwYXJhbWV0ZXJpemVfY2FsbCgKICAgICAgICAgICAgICAgICZ0LAogICAgICAgICAgICAgICAgQ2FsbFBhcmFtczo6PEVudlR5cGVzLCAoKT46Omludm9rZSh0LmNhbGxlZSwgdC5zZWxlY3Rvci5pbnRvKCkpLAogICAgICAgICAgICApCiAgICAgICAgICAgIC5maXJlKCkKICAgICAgICAgICAgLm1hcF9lcnIofF98ICgpKTsKICAgICAgICAgICAgc2VsZi5lbnYoKS5lbWl0X2V2ZW50KEV4ZWN1dGlvbiB7CiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogdHJhbnNfaWQsCiAgICAgICAgICAgICAgICByZXN1bHQ6IHJlc3VsdC5tYXAofF98IE5vbmUpLAogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmVzdWx0CiAgICAgICAgfQoKICAgICAgICAvLy8gRXZhbHVhdGUgYSBjb25maXJtZWQgZXhlY3V0aW9uIGFuZCByZXR1cm4gaXRzIG91dHB1dCBhcyBieXRlcy4KICAgICAgICAvLy8KICAgICAgICAvLy8gSXRzIHJldHVybiB2YWx1ZSBpbmRpY2F0ZXMgd2hldGhlciB0aGUgY2FsbGVkIHRyYW5zYWN0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCBjb250YWlucwogICAgICAgIC8vLyBpdHMgb3V0cHV0IHdoZW4gc3VjZXNmdWwuCiAgICAgICAgLy8vIFRoaXMgY2FuIGJlIGNhbGxlZCBieSBhbnlvbmUuCiAgICAgICAgI1tpbmsobWVzc2FnZSldCiAgICAgICAgZm4gZXZhbF90cmFuc2FjdGlvbigmbXV0IHNlbGYsIHRyYW5zX2lkOiBUcmFuc2FjdGlvbklkKSAtPiBSZXN1bHQ8VmVjPHU4PiwgKCk+IHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfY29uZmlybWVkKHRyYW5zX2lkKTsKICAgICAgICAgICAgbGV0IHQgPSBzZWxmLnRha2VfdHJhbnNhY3Rpb24odHJhbnNfaWQpLmV4cGVjdChXUk9OR19UUkFOU0FDVElPTl9JRCk7CiAgICAgICAgICAgIGxldCByZXN1bHQgPSBwYXJhbWV0ZXJpemVfY2FsbCgKICAgICAgICAgICAgICAgICZ0LAogICAgICAgICAgICAgICAgQ2FsbFBhcmFtczo6PEVudlR5cGVzLCBWZWM8dTg+Pjo6ZXZhbCh0LmNhbGxlZSwgdC5zZWxlY3Rvci5pbnRvKCkpLAogICAgICAgICAgICApCiAgICAgICAgICAgIC5maXJlKCkKICAgICAgICAgICAgLm1hcF9lcnIofF98ICgpKTsKICAgICAgICAgICAgc2VsZi5lbnYoKS5lbWl0X2V2ZW50KEV4ZWN1dGlvbiB7CiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogdHJhbnNfaWQsCiAgICAgICAgICAgICAgICByZXN1bHQ6IHJlc3VsdC5jbG9uZSgpLm1hcChTb21lKSwKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJlc3VsdAogICAgICAgIH0KCiAgICAgICAgLy8vIFNldCB0aGUgYHRyYW5zYWN0aW9uYCBhcyBjb25maXJtZWQgYnkgYGNvbmZpcm1lcmAuCiAgICAgICAgLy8vIElkZW1wb3RlbnQgb3BlcmF0aW9uIHJlZ2FyZGluZyBhbiBhbHJlYWR5IGNvbmZpcm1lZCBgdHJhbnNhY3Rpb25gCiAgICAgICAgLy8vIGJ5IGBjb25maXJtZXJgLgogICAgICAgIGZuIGNvbmZpcm1fYnlfY2FsbGVyKAogICAgICAgICAgICAmbXV0IHNlbGYsCiAgICAgICAgICAgIGNvbmZpcm1lcjogQWNjb3VudElkLAogICAgICAgICAgICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25JZCwKICAgICAgICApIC0+IENvbmZpcm1hdGlvblN0YXR1cyB7CiAgICAgICAgICAgIGxldCBjb3VudCA9IHNlbGYuY29uZmlybWF0aW9uX2NvdW50LmVudHJ5KHRyYW5zYWN0aW9uKS5vcl9pbnNlcnQoMCk7CiAgICAgICAgICAgIGxldCBuZXdfY29uZmlybWF0aW9uID0gc2VsZgogICAgICAgICAgICAgICAgLmNvbmZpcm1hdGlvbnMKICAgICAgICAgICAgICAgIC5pbnNlcnQoKHRyYW5zYWN0aW9uLCBjb25maXJtZXIpLCAoKSkKICAgICAgICAgICAgICAgIC5pc19ub25lKCk7CiAgICAgICAgICAgIGlmIG5ld19jb25maXJtYXRpb24gewogICAgICAgICAgICAgICAgKmNvdW50ICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IHN0YXR1cyA9IHsKICAgICAgICAgICAgICAgIGlmICpjb3VudCA+PSAqc2VsZi5yZXF1aXJlbWVudCB7CiAgICAgICAgICAgICAgICAgICAgQ29uZmlybWF0aW9uU3RhdHVzOjpDb25maXJtZWQKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgQ29uZmlybWF0aW9uU3RhdHVzOjpDb25maXJtYXRpb25zTmVlZGVkKCpzZWxmLnJlcXVpcmVtZW50IC0gKmNvdW50KQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgICBpZiBuZXdfY29uZmlybWF0aW9uIHsKICAgICAgICAgICAgICAgIHNlbGYuZW52KCkuZW1pdF9ldmVudChDb25maXJtYXRpb24gewogICAgICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uLAogICAgICAgICAgICAgICAgICAgIGZyb206IGNvbmZpcm1lciwKICAgICAgICAgICAgICAgICAgICBzdGF0dXMsCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdGF0dXMKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgdGhlIGluZGV4IG9mIGBvd25lcmAgaW4gYHNlbGYub3duZXJzYC4KICAgICAgICAvLy8gUGFuaWNzIGlmIGBvd25lcmAgaXMgbm90IGZvdW5kIGluIGBzZWxmLm93bmVyc2AuCiAgICAgICAgZm4gb3duZXJfaW5kZXgoJnNlbGYsIG93bmVyOiAmQWNjb3VudElkKSAtPiB1MzIgewogICAgICAgICAgICBzZWxmLm93bmVycy5pdGVyKCkucG9zaXRpb24ofHh8ICp4ID09ICpvd25lcikuZXhwZWN0KAogICAgICAgICAgICAgICAgIlRoaXMgaXMgb25seSBjYWxsZWQgYWZ0ZXIgaXQgd2FzIGFscmVhZHkgdmVyaWZpZWQgdGhhdCB0aGUgaWQgaXMKICAgICAgICAgICAgICAgICBhY3R1YWxseSBhbiBvd25lci4iLAogICAgICAgICAgICApIGFzIHUzMgogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZSB0aGUgdHJhbnNhY3Rpb24gaWRlbnRpZmllZCBieSBgdHJhbnNfaWRgIGZyb20gYHNlbGYudHJhbnNhY3Rpb25zYC4KICAgICAgICAvLy8gQWxzbyByZW1vdmVzIGFsbCBjb25maXJtYXRpb24gc3RhdGUgYXNzb2NpYXRlZCB3aXRoIGl0LgogICAgICAgIGZuIHRha2VfdHJhbnNhY3Rpb24oJm11dCBzZWxmLCB0cmFuc19pZDogVHJhbnNhY3Rpb25JZCkgLT4gT3B0aW9uPFRyYW5zYWN0aW9uPiB7CiAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvbiA9IHNlbGYudHJhbnNhY3Rpb25zLnRha2UodHJhbnNfaWQpOwogICAgICAgICAgICBpZiB0cmFuc2FjdGlvbi5pc19zb21lKCkgewogICAgICAgICAgICAgICAgc2VsZi5jbGVhbl90cmFuc2FjdGlvbl9jb25maXJtYXRpb25zKHRyYW5zX2lkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cmFuc2FjdGlvbgogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZSBhbGwgY29uZmlybWF0aW9uIHN0YXRlIGFzc29jaWF0ZWQgd2l0aCBgb3duZXJgLgogICAgICAgIC8vLyBBbHNvIGFkanVzdHMgdGhlIGBzZWxmLmNvbmZpcm1hdGlvbl9jb3VudGAgdmFyaWFibGUuCiAgICAgICAgZm4gY2xlYW5fb3duZXJfY29uZmlybWF0aW9ucygmbXV0IHNlbGYsIG93bmVyOiAmQWNjb3VudElkKSB7CiAgICAgICAgICAgIGZvciAodHJhbnNfaWQsIF8pIGluIHNlbGYudHJhbnNhY3Rpb25zLml0ZXIoKSB7CiAgICAgICAgICAgICAgICBpZiBzZWxmLmNvbmZpcm1hdGlvbnMucmVtb3ZlKCYodHJhbnNfaWQsICpvd25lcikpLmlzX3NvbWUoKSB7CiAgICAgICAgICAgICAgICAgICAgKnNlbGYuY29uZmlybWF0aW9uX2NvdW50LmVudHJ5KHRyYW5zX2lkKS5vcl9pbnNlcnQoMCkgKz0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIFRoaXMgcmVtb3ZlcyBhbGwgY29uZmlybWF0aW9uIHN0YXRlIGFzc29jaWF0ZWQgd2l0aCBgdHJhbnNhY3Rpb25gLgogICAgICAgIGZuIGNsZWFuX3RyYW5zYWN0aW9uX2NvbmZpcm1hdGlvbnMoJm11dCBzZWxmLCB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25JZCkgewogICAgICAgICAgICBmb3Igb3duZXIgaW4gc2VsZi5vd25lcnMuaXRlcigpIHsKICAgICAgICAgICAgICAgIHNlbGYuY29uZmlybWF0aW9ucy5yZW1vdmUoJih0cmFuc2FjdGlvbiwgKm93bmVyKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VsZi5jb25maXJtYXRpb25fY291bnQucmVtb3ZlKCZ0cmFuc2FjdGlvbik7CiAgICAgICAgfQoKICAgICAgICAvLy8gUGFuaWMgaWYgdHJhbnNhY3Rpb24gYHRyYW5zX2lkYCBpcyBub3QgY29uZmlybWVkIGJ5IGF0IGxlYXN0CiAgICAgICAgLy8vIGBzZWxmLnJlcXVpcmVtZW50YCBvd25lcnMuCiAgICAgICAgZm4gZW5zdXJlX2NvbmZpcm1lZCgmc2VsZiwgdHJhbnNfaWQ6IFRyYW5zYWN0aW9uSWQpIHsKICAgICAgICAgICAgYXNzZXJ0ISgKICAgICAgICAgICAgICAgIHNlbGYuY29uZmlybWF0aW9uX2NvdW50CiAgICAgICAgICAgICAgICAgICAgLmdldCgmdHJhbnNfaWQpCiAgICAgICAgICAgICAgICAgICAgLmV4cGVjdChXUk9OR19UUkFOU0FDVElPTl9JRCkKICAgICAgICAgICAgICAgICAgICA+PSBzZWxmLnJlcXVpcmVtZW50LmdldCgpCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAvLy8gUGFuaWMgaWYgdGhlIHRyYW5zYWN0aW9uIGB0cmFuc19pZGAgZG9lcyBub3QgZXhpdC4KICAgICAgICBmbiBlbnN1cmVfdHJhbnNhY3Rpb25fZXhpc3RzKCZzZWxmLCB0cmFuc19pZDogVHJhbnNhY3Rpb25JZCkgewogICAgICAgICAgICBzZWxmLnRyYW5zYWN0aW9ucy5nZXQodHJhbnNfaWQpLmV4cGVjdChXUk9OR19UUkFOU0FDVElPTl9JRCk7CiAgICAgICAgfQoKICAgICAgICAvLy8gUGFuaWMgaWYgdGhlIHNlbmRlciBpcyBubyBvd25lciBvZiB0aGUgd2FsbGV0LgogICAgICAgIGZuIGVuc3VyZV9jYWxsZXJfaXNfb3duZXIoJnNlbGYpIHsKICAgICAgICAgICAgc2VsZi5lbnN1cmVfb3duZXIoJnNlbGYuZW52KCkuY2FsbGVyKCkpOwogICAgICAgIH0KCiAgICAgICAgLy8vIFBhbmljIGlmIHRoZSBzZW5kZXIgaXMgbm90IHRoaXMgd2FsbGV0LgogICAgICAgIGZuIGVuc3VyZV9mcm9tX3dhbGxldCgmc2VsZikgewogICAgICAgICAgICBhc3NlcnRfZXEhKHNlbGYuZW52KCkuY2FsbGVyKCksIHNlbGYuZW52KCkuYWNjb3VudF9pZCgpKTsKICAgICAgICB9CgogICAgICAgIC8vLyBQYW5pYyBpZiBgb3duZXJgIGlzIG5vdCBhbiBvd25lciwKICAgICAgICBmbiBlbnN1cmVfb3duZXIoJnNlbGYsIG93bmVyOiAmQWNjb3VudElkKSB7CiAgICAgICAgICAgIGFzc2VydCEoc2VsZi5pc19vd25lci5jb250YWluc19rZXkob3duZXIpKTsKICAgICAgICB9CgogICAgICAgIC8vLyBQYW5pYyBpZiBgb3duZXJgIGlzIGFuIG93bmVyLgogICAgICAgIGZuIGVuc3VyZV9ub19vd25lcigmc2VsZiwgb3duZXI6ICZBY2NvdW50SWQpIHsKICAgICAgICAgICAgYXNzZXJ0ISghc2VsZi5pc19vd25lci5jb250YWluc19rZXkob3duZXIpKTsKICAgICAgICB9CiAgICB9CgogICAgLy8vIFBhcmFtZXRlcml6ZSBhIGNhbGwgd2l0aCB0aGUgYXJndW1lbnRzIHN0b3JlZCBpbnNpZGUgYSB0cmFuc2FjdGlvbi4KICAgIGZuIHBhcmFtZXRlcml6ZV9jYWxsPFI+KAogICAgICAgIHQ6ICZUcmFuc2FjdGlvbiwKICAgICAgICBidWlsZGVyOiBDYWxsQnVpbGRlcjxFbnZUeXBlcywgUiwgVW5zZWFsZWQ+LAogICAgKSAtPiBDYWxsQnVpbGRlcjxFbnZUeXBlcywgUiwgU2VhbGVkPiB7CiAgICAgICAgYnVpbGRlcgogICAgICAgICAgICAuZ2FzX2xpbWl0KHQuZ2FzX2xpbWl0KQogICAgICAgICAgICAudHJhbnNmZXJyZWRfdmFsdWUodC50cmFuc2ZlcnJlZF92YWx1ZSkKICAgICAgICAgICAgLnB1c2hfYXJnKCZDYWxsSW5wdXQoJnQuaW5wdXQpKQogICAgICAgICAgICAuc2VhbCgpCiAgICB9CgogICAgLy8vIFBhbmljIGlmIHRoZSBudW1iZXIgb2YgYG93bmVyc2AgdW5kZXIgYSBgcmVxdWlyZW1lbnRgIHZpb2xhdGVzIG91cgogICAgLy8vIHJlcXVpcmVtZW50IGludmFyaWFudC4KICAgIGZuIGVuc3VyZV9yZXF1aXJlbWVudF9pc192YWxpZChvd25lcnM6IHUzMiwgcmVxdWlyZW1lbnQ6IHUzMikgewogICAgICAgIGFzc2VydCEoMCA8IHJlcXVpcmVtZW50ICYmIHJlcXVpcmVtZW50IDw9IG93bmVycyAmJiBvd25lcnMgPD0gTUFYX09XTkVSUyk7CiAgICB9CgogICAgI1tjZmcodGVzdCldCiAgICBtb2QgdGVzdHMgewogICAgICAgIHVzZSBzdXBlcjo6KjsKICAgICAgICB1c2UgaW5rX2NvcmU6OmVudjo6ewogICAgICAgICAgICBjYWxsLAogICAgICAgICAgICB0ZXN0LAogICAgICAgIH07CiAgICAgICAgdHlwZSBBY2NvdW50cyA9IHRlc3Q6OkRlZmF1bHRBY2NvdW50czxFbnZUeXBlcz47CiAgICAgICAgY29uc3QgV0FMTEVUOiBbdTg7IDMyXSA9IFs3OyAzMl07CgogICAgICAgIGltcGwgVHJhbnNhY3Rpb24gewogICAgICAgICAgICBmbiBjaGFuZ2VfcmVxdWlyZW1lbnQocmVxdWlyZW1lbnQ6IHUzMikgLT4gU2VsZiB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IGNhbGwgPQogICAgICAgICAgICAgICAgICAgIGNhbGw6OkNhbGxEYXRhOjpuZXcoY2FsbDo6U2VsZWN0b3I6OmZyb21fc3RyKCJjaGFuZ2VfcmVxdWlyZW1lbnQiKSk7CiAgICAgICAgICAgICAgICBjYWxsLnB1c2hfYXJnKCZyZXF1aXJlbWVudCk7CiAgICAgICAgICAgICAgICBTZWxmIHsKICAgICAgICAgICAgICAgICAgICBjYWxsZWU6IFdBTExFVC5pbnRvKCksCiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6IGNhbGwuc2VsZWN0b3IoKS50b19ieXRlcygpLAogICAgICAgICAgICAgICAgICAgIGlucHV0OiBjYWxsLnBhcmFtcygpLnRvX293bmVkKCksCiAgICAgICAgICAgICAgICAgICAgdHJhbnNmZXJyZWRfdmFsdWU6IDAsCiAgICAgICAgICAgICAgICAgICAgZ2FzX2xpbWl0OiAxMDAwMDAwLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmbiBzZXRfc2VuZGVyKHNlbmRlcjogQWNjb3VudElkKSB7CiAgICAgICAgICAgIHRlc3Q6OnB1c2hfZXhlY3V0aW9uX2NvbnRleHQ6OjxFbnZUeXBlcz4oCiAgICAgICAgICAgICAgICBzZW5kZXIsCiAgICAgICAgICAgICAgICBXQUxMRVQuaW50bygpLAogICAgICAgICAgICAgICAgMTAwMDAwMCwKICAgICAgICAgICAgICAgIDEwMDAwMDAsCiAgICAgICAgICAgICAgICBjYWxsOjpDYWxsRGF0YTo6bmV3KGNhbGw6OlNlbGVjdG9yOjpmcm9tX3N0cigiZHVtbXkiKSksCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBmbiBzZXRfZnJvbV93YWxsZXQoKSB7CiAgICAgICAgICAgIHNldF9zZW5kZXIoV0FMTEVULmludG8oKSk7CiAgICAgICAgfQoKICAgICAgICBmbiBzZXRfZnJvbV9vd25lcigpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBzZXRfc2VuZGVyKGFjY291bnRzLmFsaWNlKTsKICAgICAgICB9CgogICAgICAgIGZuIHNldF9mcm9tX25vb3duZXIoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgc2V0X3NlbmRlcihhY2NvdW50cy5kamFuZ28pOwogICAgICAgIH0KCiAgICAgICAgZm4gZGVmYXVsdF9hY2NvdW50cygpIC0+IEFjY291bnRzIHsKICAgICAgICAgICAgdGVzdDo6ZGVmYXVsdF9hY2NvdW50cygpCiAgICAgICAgICAgICAgICAuZXhwZWN0KCJUZXN0IGVudmlyb25tZW50IGlzIGV4cGVjdGVkIHRvIGJlIGluaXRpYWxpemVkLiIpCiAgICAgICAgfQoKICAgICAgICBmbiBidWlsZF9jb250cmFjdCgpIC0+IE11bHRpc2lnUGxhaW4gewogICAgICAgICAgICBsZXQgYWNjb3VudHMgPSBkZWZhdWx0X2FjY291bnRzKCk7CiAgICAgICAgICAgIGxldCBvd25lcnMgPSBpbmtfcHJlbHVkZTo6dmVjIVthY2NvdW50cy5hbGljZSwgYWNjb3VudHMuYm9iLCBhY2NvdW50cy5ldmVdOwogICAgICAgICAgICBNdWx0aXNpZ1BsYWluOjpuZXcoMiwgb3duZXJzKQogICAgICAgIH0KCiAgICAgICAgZm4gc3VibWl0X3RyYW5zYWN0aW9uKCkgLT4gTXVsdGlzaWdQbGFpbiB7CiAgICAgICAgICAgIGxldCBtdXQgY29udHJhY3QgPSBidWlsZF9jb250cmFjdCgpOwogICAgICAgICAgICBsZXQgYWNjb3VudHMgPSBkZWZhdWx0X2FjY291bnRzKCk7CiAgICAgICAgICAgIHNldF9mcm9tX293bmVyKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LnN1Ym1pdF90cmFuc2FjdGlvbihUcmFuc2FjdGlvbjo6Y2hhbmdlX3JlcXVpcmVtZW50KDEpKTsKICAgICAgICAgICAgYXNzZXJ0X2VxIShjb250cmFjdC50cmFuc2FjdGlvbnMubGVuKCksIDEpOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDIpOwogICAgICAgICAgICBsZXQgdHJhbnNhY3Rpb24gPSBjb250cmFjdC50cmFuc2FjdGlvbnMuZ2V0KDApLnVud3JhcCgpOwogICAgICAgICAgICBhc3NlcnRfZXEhKCp0cmFuc2FjdGlvbiwgVHJhbnNhY3Rpb246OmNoYW5nZV9yZXF1aXJlbWVudCgxKSk7CiAgICAgICAgICAgIGNvbnRyYWN0LmNvbmZpcm1hdGlvbnMuZ2V0KCYoMCwgYWNjb3VudHMuYWxpY2UpKS51bndyYXAoKTsKICAgICAgICAgICAgYXNzZXJ0X2VxIShjb250cmFjdC5jb25maXJtYXRpb25zLmxlbigpLCAxKTsKICAgICAgICAgICAgYXNzZXJ0X2VxISgqY29udHJhY3QuY29uZmlybWF0aW9uX2NvdW50LmdldCgmMCkudW53cmFwKCksIDEpOwogICAgICAgICAgICBjb250cmFjdAogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgIGZuIGNvbnN0cnVjdGlvbl93b3JrcygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgb3duZXJzID0gaW5rX3ByZWx1ZGU6OnZlYyFbYWNjb3VudHMuYWxpY2UsIGFjY291bnRzLmJvYiwgYWNjb3VudHMuZXZlXTsKICAgICAgICAgICAgbGV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKCiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3Qub3duZXJzLmxlbigpLCAzKTsKICAgICAgICAgICAgYXNzZXJ0X2VxISgqY29udHJhY3QucmVxdWlyZW1lbnQuZ2V0KCksIDIpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0Lm93bmVycy5pdGVyKCkuZXEob3duZXJzLml0ZXIoKSkpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0LmlzX293bmVyLmdldCgmYWNjb3VudHMuYWxpY2UpLmlzX3NvbWUoKSk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuaXNfb3duZXIuZ2V0KCZhY2NvdW50cy5ib2IpLmlzX3NvbWUoKSk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuaXNfb3duZXIuZ2V0KCZhY2NvdW50cy5ldmUpLmlzX3NvbWUoKSk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuaXNfb3duZXIuZ2V0KCZhY2NvdW50cy5jaGFybGllKS5pc19ub25lKCkpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0LmlzX293bmVyLmdldCgmYWNjb3VudHMuZGphbmdvKS5pc19ub25lKCkpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0LmlzX293bmVyLmdldCgmYWNjb3VudHMuZnJhbmspLmlzX25vbmUoKSk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3QuY29uZmlybWF0aW9ucy5sZW4oKSwgMCk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3QuY29uZmlybWF0aW9uX2NvdW50LmxlbigpLCAwKTsKICAgICAgICAgICAgYXNzZXJ0X2VxIShjb250cmFjdC50cmFuc2FjdGlvbnMubGVuKCksIDApOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIGVtcHR5X293bmVyX2NvbnN0cnVjdGlvbl9mYWlscygpIHsKICAgICAgICAgICAgTXVsdGlzaWdQbGFpbjo6bmV3KDAsIHZlYyFbXSk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gemVyb19yZXF1aXJlbWVudF9jb25zdHJ1Y3Rpb25fZmFpbHMoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgTXVsdGlzaWdQbGFpbjo6bmV3KDAsIHZlYyFbYWNjb3VudHMuYWxpY2UsIGFjY291bnRzLmJvYl0pOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIHRvb19sYXJnZV9yZXF1aXJlbWVudF9jb25zdHJ1Y3Rpb25fZmFpbHMoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgTXVsdGlzaWdQbGFpbjo6bmV3KDMsIHZlYyFbYWNjb3VudHMuYWxpY2UsIGFjY291bnRzLmJvYl0pOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgIGZuIGFkZF9vd25lcl93b3JrcygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGxldCBvd25lcnMgPSBjb250cmFjdC5vd25lcnMubGVuKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmFkZF9vd25lcihhY2NvdW50cy5mcmFuayk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3Qub3duZXJzLmxlbigpLCBvd25lcnMgKyAxKTsKICAgICAgICAgICAgYXNzZXJ0IShjb250cmFjdC5pc19vd25lci5nZXQoJmFjY291bnRzLmZyYW5rKS5pc19zb21lKCkpOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDEpOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIGFkZF9leGlzdGluZ19vd25lcl9mYWlscygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmFkZF9vd25lcihhY2NvdW50cy5ib2IpOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIGFkZF9vd25lcl9wZXJtaXNzaW9uX2RlbmllZCgpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fb3duZXIoKTsKICAgICAgICAgICAgY29udHJhY3QuYWRkX293bmVyKGFjY291bnRzLmZyYW5rKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiByZW1vdmVfb3duZXJfd29ya3MoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IGJ1aWxkX2NvbnRyYWN0KCk7CiAgICAgICAgICAgIHNldF9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBsZXQgb3duZXJzID0gY29udHJhY3Qub3duZXJzLmxlbigpOwogICAgICAgICAgICBjb250cmFjdC5yZW1vdmVfb3duZXIoYWNjb3VudHMuYWxpY2UpOwogICAgICAgICAgICBhc3NlcnRfZXEhKGNvbnRyYWN0Lm93bmVycy5sZW4oKSwgb3duZXJzIC0gMSk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuaXNfb3duZXIuZ2V0KCZhY2NvdW50cy5hbGljZSkuaXNfbm9uZSgpKTsKICAgICAgICAgICAgYXNzZXJ0X2VxISh0ZXN0OjpyZWNvcmRlZF9ldmVudHMoKS5jb3VudCgpLCAxKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICAjW3Nob3VsZF9wYW5pY10KICAgICAgICBmbiByZW1vdmVfb3duZXJfbm9uZXhpc3RpbmdfZmFpbHMoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IGJ1aWxkX2NvbnRyYWN0KCk7CiAgICAgICAgICAgIHNldF9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBjb250cmFjdC5yZW1vdmVfb3duZXIoYWNjb3VudHMuZGphbmdvKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICAjW3Nob3VsZF9wYW5pY10KICAgICAgICBmbiByZW1vdmVfb3duZXJfcGVybWlzc2lvbl9kZW5pZWQoKSB7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IGJ1aWxkX2NvbnRyYWN0KCk7CiAgICAgICAgICAgIHNldF9mcm9tX293bmVyKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LnJlbW92ZV9vd25lcihhY2NvdW50cy5hbGljZSk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgZm4gcmVwbGFjZV9vd25lcl93b3JrcygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGxldCBvd25lcnMgPSBjb250cmFjdC5vd25lcnMubGVuKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LnJlcGxhY2Vfb3duZXIoYWNjb3VudHMuYWxpY2UsIGFjY291bnRzLmRqYW5nbyk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3Qub3duZXJzLmxlbigpLCBvd25lcnMpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0LmlzX293bmVyLmdldCgmYWNjb3VudHMuYWxpY2UpLmlzX25vbmUoKSk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuaXNfb3duZXIuZ2V0KCZhY2NvdW50cy5kamFuZ28pLmlzX3NvbWUoKSk7CiAgICAgICAgICAgIGFzc2VydF9lcSEodGVzdDo6cmVjb3JkZWRfZXZlbnRzKCkuY291bnQoKSwgMik7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gcmVwbGFjZV9vd25lcl9leGlzdGluZ19mYWlscygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGNvbnRyYWN0LnJlcGxhY2Vfb3duZXIoYWNjb3VudHMuYWxpY2UsIGFjY291bnRzLmJvYik7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gcmVwbGFjZV9vd25lcl9ub25leGlzdGluZ19mYWlscygpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGNvbnRyYWN0LnJlcGxhY2Vfb3duZXIoYWNjb3VudHMuZGphbmdvLCBhY2NvdW50cy5mcmFuayk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gcmVwbGFjZV9vd25lcl9wZXJtaXNzaW9uX2RlbmllZCgpIHsKICAgICAgICAgICAgbGV0IGFjY291bnRzID0gZGVmYXVsdF9hY2NvdW50cygpOwogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fb3duZXIoKTsKICAgICAgICAgICAgY29udHJhY3QucmVwbGFjZV9vd25lcihhY2NvdW50cy5hbGljZSwgYWNjb3VudHMuZGphbmdvKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiBjaGFuZ2VfcmVxdWlyZW1lbnRfd29ya3MoKSB7CiAgICAgICAgICAgIGxldCBtdXQgY29udHJhY3QgPSBidWlsZF9jb250cmFjdCgpOwogICAgICAgICAgICBhc3NlcnRfZXEhKCpjb250cmFjdC5yZXF1aXJlbWVudC5nZXQoKSwgMik7CiAgICAgICAgICAgIHNldF9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBjb250cmFjdC5jaGFuZ2VfcmVxdWlyZW1lbnQoMyk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoKmNvbnRyYWN0LnJlcXVpcmVtZW50LmdldCgpLCAzKTsKICAgICAgICAgICAgYXNzZXJ0X2VxISh0ZXN0OjpyZWNvcmRlZF9ldmVudHMoKS5jb3VudCgpLCAxKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICAjW3Nob3VsZF9wYW5pY10KICAgICAgICBmbiBjaGFuZ2VfcmVxdWlyZW1lbnRfdG9vX2hpZ2goKSB7CiAgICAgICAgICAgIGxldCBtdXQgY29udHJhY3QgPSBidWlsZF9jb250cmFjdCgpOwogICAgICAgICAgICBzZXRfZnJvbV93YWxsZXQoKTsKICAgICAgICAgICAgY29udHJhY3QuY2hhbmdlX3JlcXVpcmVtZW50KDQpOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIGNoYW5nZV9yZXF1aXJlbWVudF96ZXJvX2ZhaWxzKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmNoYW5nZV9yZXF1aXJlbWVudCgwKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiBzdWJtaXRfdHJhbnNhY3Rpb25fd29ya3MoKSB7CiAgICAgICAgICAgIHN1Ym1pdF90cmFuc2FjdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIHN1Ym1pdF90cmFuc2FjdGlvbl9ub293bmVyX2ZhaWxzKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gYnVpbGRfY29udHJhY3QoKTsKICAgICAgICAgICAgc2V0X2Zyb21fbm9vd25lcigpOwogICAgICAgICAgICBjb250cmFjdC5zdWJtaXRfdHJhbnNhY3Rpb24oVHJhbnNhY3Rpb246OmNoYW5nZV9yZXF1aXJlbWVudCgxKSk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gc3VibWl0X3RyYW5zYWN0aW9uX3dhbGxldF9mYWlscygpIHsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IGJ1aWxkX2NvbnRyYWN0KCk7CiAgICAgICAgICAgIHNldF9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBjb250cmFjdC5zdWJtaXRfdHJhbnNhY3Rpb24oVHJhbnNhY3Rpb246OmNoYW5nZV9yZXF1aXJlbWVudCgxKSk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgZm4gY2FuY2VsX3RyYW5zYWN0aW9uX3dvcmtzKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gc3VibWl0X3RyYW5zYWN0aW9uKCk7CiAgICAgICAgICAgIHNldF9mcm9tX3dhbGxldCgpOwogICAgICAgICAgICBjb250cmFjdC5jYW5jZWxfdHJhbnNhY3Rpb24oMCk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3QudHJhbnNhY3Rpb25zLmxlbigpLCAwKTsKICAgICAgICAgICAgYXNzZXJ0X2VxISh0ZXN0OjpyZWNvcmRlZF9ldmVudHMoKS5jb3VudCgpLCAzKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiBjYW5jZWxfdHJhbnNhY3Rpb25fbm9uZXhpc3RpbmcoKSB7CiAgICAgICAgICAgIGxldCBtdXQgY29udHJhY3QgPSBzdWJtaXRfdHJhbnNhY3Rpb24oKTsKICAgICAgICAgICAgc2V0X2Zyb21fd2FsbGV0KCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmNhbmNlbF90cmFuc2FjdGlvbigxKTsKICAgICAgICAgICAgYXNzZXJ0X2VxIShjb250cmFjdC50cmFuc2FjdGlvbnMubGVuKCksIDEpOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDIpOwogICAgICAgIH0KCiAgICAgICAgI1t0ZXN0XQogICAgICAgICNbc2hvdWxkX3BhbmljXQogICAgICAgIGZuIGNhbmNlbF90cmFuc2FjdGlvbl9ub19wZXJtaXNzaW9uKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gc3VibWl0X3RyYW5zYWN0aW9uKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmNhbmNlbF90cmFuc2FjdGlvbigwKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiBjb25maXJtX3RyYW5zYWN0aW9uX3dvcmtzKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gc3VibWl0X3RyYW5zYWN0aW9uKCk7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgc2V0X3NlbmRlcihhY2NvdW50cy5ib2IpOwogICAgICAgICAgICBjb250cmFjdC5jb25maXJtX3RyYW5zYWN0aW9uKDApOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDMpOwogICAgICAgICAgICBjb250cmFjdC5jb25maXJtYXRpb25zLmdldCgmKDAsIGFjY291bnRzLmJvYikpLnVud3JhcCgpOwogICAgICAgICAgICBhc3NlcnRfZXEhKGNvbnRyYWN0LmNvbmZpcm1hdGlvbnMubGVuKCksIDIpOwogICAgICAgICAgICBhc3NlcnRfZXEhKCpjb250cmFjdC5jb25maXJtYXRpb25fY291bnQuZ2V0KCYwKS51bndyYXAoKSwgMik7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgZm4gY29uZmlybV90cmFuc2FjdGlvbl9hbHJlYWR5X2NvbmZpcm1lZCgpIHsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IHN1Ym1pdF90cmFuc2FjdGlvbigpOwogICAgICAgICAgICBsZXQgYWNjb3VudHMgPSBkZWZhdWx0X2FjY291bnRzKCk7CiAgICAgICAgICAgIHNldF9zZW5kZXIoYWNjb3VudHMuYWxpY2UpOwogICAgICAgICAgICBjb250cmFjdC5jb25maXJtX3RyYW5zYWN0aW9uKDApOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDIpOwogICAgICAgICAgICBjb250cmFjdC5jb25maXJtYXRpb25zLmdldCgmKDAsIGFjY291bnRzLmFsaWNlKSkudW53cmFwKCk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3QuY29uZmlybWF0aW9ucy5sZW4oKSwgMSk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoKmNvbnRyYWN0LmNvbmZpcm1hdGlvbl9jb3VudC5nZXQoJjApLnVud3JhcCgpLCAxKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICAjW3Nob3VsZF9wYW5pY10KICAgICAgICBmbiBjb25maXJtX3RyYW5zYWN0aW9uX25vb3duZXJfZmFpbCgpIHsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IHN1Ym1pdF90cmFuc2FjdGlvbigpOwogICAgICAgICAgICBzZXRfZnJvbV9ub293bmVyKCk7CiAgICAgICAgICAgIGNvbnRyYWN0LmNvbmZpcm1fdHJhbnNhY3Rpb24oMCk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgZm4gcmV2b2tlX3RyYW5zYWN0aW9uX3dvcmtzKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gc3VibWl0X3RyYW5zYWN0aW9uKCk7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgc2V0X3NlbmRlcihhY2NvdW50cy5hbGljZSk7CiAgICAgICAgICAgIGNvbnRyYWN0LnJldm9rZV9jb25maXJtYXRpb24oMCk7CiAgICAgICAgICAgIGFzc2VydF9lcSEodGVzdDo6cmVjb3JkZWRfZXZlbnRzKCkuY291bnQoKSwgMyk7CiAgICAgICAgICAgIGFzc2VydCEoY29udHJhY3QuY29uZmlybWF0aW9ucy5nZXQoJigwLCBhY2NvdW50cy5hbGljZSkpLmlzX25vbmUoKSk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoY29udHJhY3QuY29uZmlybWF0aW9ucy5sZW4oKSwgMCk7CiAgICAgICAgICAgIGFzc2VydF9lcSEoKmNvbnRyYWN0LmNvbmZpcm1hdGlvbl9jb3VudC5nZXQoJjApLnVud3JhcCgpLCAwKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiByZXZva2VfdHJhbnNhY3Rpb25fbm9fY29uZmlybWVyKCkgewogICAgICAgICAgICBsZXQgbXV0IGNvbnRyYWN0ID0gc3VibWl0X3RyYW5zYWN0aW9uKCk7CiAgICAgICAgICAgIGxldCBhY2NvdW50cyA9IGRlZmF1bHRfYWNjb3VudHMoKTsKICAgICAgICAgICAgc2V0X3NlbmRlcihhY2NvdW50cy5ib2IpOwogICAgICAgICAgICBjb250cmFjdC5yZXZva2VfY29uZmlybWF0aW9uKDApOwogICAgICAgICAgICBhc3NlcnRfZXEhKHRlc3Q6OnJlY29yZGVkX2V2ZW50cygpLmNvdW50KCksIDIpOwogICAgICAgICAgICBhc3NlcnQhKGNvbnRyYWN0LmNvbmZpcm1hdGlvbnMuZ2V0KCYoMCwgYWNjb3VudHMuYWxpY2UpKS5pc19zb21lKCkpOwogICAgICAgICAgICBhc3NlcnRfZXEhKGNvbnRyYWN0LmNvbmZpcm1hdGlvbnMubGVuKCksIDEpOwogICAgICAgICAgICBhc3NlcnRfZXEhKCpjb250cmFjdC5jb25maXJtYXRpb25fY291bnQuZ2V0KCYwKS51bndyYXAoKSwgMSk7CiAgICAgICAgfQoKICAgICAgICAjW3Rlc3RdCiAgICAgICAgI1tzaG91bGRfcGFuaWNdCiAgICAgICAgZm4gcmV2b2tlX3RyYW5zYWN0aW9uX25vb3duZXJfZmFpbCgpIHsKICAgICAgICAgICAgbGV0IG11dCBjb250cmFjdCA9IHN1Ym1pdF90cmFuc2FjdGlvbigpOwogICAgICAgICAgICBsZXQgYWNjb3VudHMgPSBkZWZhdWx0X2FjY291bnRzKCk7CiAgICAgICAgICAgIHNldF9zZW5kZXIoYWNjb3VudHMuZGphbmdvKTsKICAgICAgICAgICAgY29udHJhY3QucmV2b2tlX2NvbmZpcm1hdGlvbigwKTsKICAgICAgICB9CgogICAgICAgICNbdGVzdF0KICAgICAgICBmbiBleGVjdXRlX3RyYW5zYWN0aW9uX3dvcmtzKCkgewogICAgICAgICAgICAvLyBFeGVjdXRpb24gb2YgY2FsbHMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGluIG9mZi1jaGFpbiB0ZXN0LgogICAgICAgICAgICAvLyBDYWxsaW5nIGV4ZWN1dGVfdHJhbnNhY3Rpb24gcGFuaWNzIGluIGFueSBjYXNlLgogICAgICAgIH0KICAgIH0KfQ=="}' | jq } function safepkt_backend_02_program_verification() { curl --no-progress-meter -XPOST "${SCHEME_HOST}"/program-verification/efc7ed4ad2 | jq } function safepkt_backend_03_get_program_verification_progress() { curl --no-progress-meter -XGET "${SCHEME_HOST}"/program-verification/efc7ed4ad2/progress | jq } function safepkt_backend_04_get_program_verification_report() { curl --no-progress-meter -XGET "${SCHEME_HOST}"/program-verification/efc7ed4ad2/report | jq } function safepkt_backend_05_get_program_fuzzing() { curl --no-progress-meter -XPOST "${SCHEME_HOST}"/program-fuzzing/efc7ed4ad2 | jq } function safepkt_backend_06_get_program_fuzzing_report() { curl --no-progress-meter -XGET "${SCHEME_HOST}"/program-fuzzing/efc7ed4ad2/progress | jq } function safepkt_backend_07_get_program_fuzzing_report() { curl --no-progress-meter -XGET "${SCHEME_HOST}"/program-fuzzing/efc7ed4ad2/report | jq } function safepkt_backend_08_list_uploaded_sources() { local project_id project_id="$(curl --no-progress-meter --request POST \ --url "${SCHEME_HOST}"/source \ --header 'Content-Type: application/json' \ --data '{"source": "'$(echo -n '' | openssl base64)'"}' | jq '.project_id' | sed -e 's/"//g')" && /bin/bash -c "curl --no-progress-meter -XPOST "${SCHEME_HOST}"/program-verification/${project_id}" >>/dev/null 2>&1 && /bin/bash -c "curl --no-progress-meter -XPOST ""${SCHEME_HOST}""/uploaded-sources-listing/${project_id}" >>/dev/null 2>&1 && /bin/bash -c "curl --no-progress-meter -XGET ""${SCHEME_HOST}""/uploaded-sources-listing/${project_id}/report" | jq } function safepkt_backend_09_stop_verification() { curl --no-progress-meter -XDELETE "${SCHEME_HOST}"/program-verification/efc7ed4ad2 | jq }